题目大意:给出一个不超过九位的数,按照中文读法输出,并且注意"0"的读法,比如,10100,要读成 "yi Wan ling yi Bai"。
非常繁琐的一道题,主要的问题在于”0“的读法,处理这一问题的策略是,按照从高位到低位,顺序读入每个数。设置一个变量表明是否应当输出"ling"。如果当前读到了非零数字,而且与前一个非零数字中间有0的话,除了一种情况外,都应该输出”ling",例如10200,读到2时,由于与前一个非零数字1之间有0,就应当输出"ling“。这个例外情况是,万位上是0,但整个万节大于0,读到万位时应当输出"Wan",读千位及后面的位时,应当忽略万位上的0。例如,301000,应当是"san Shi Wan yi Qian",即使千位的1前面有0,但是因为这个0在万位上,所以不输出"ling"。
当然,这个逻辑看起来很复杂,实现起来不难,如果设置变量printLing 表明是否应当输出"ling"的话,将它的初值设置为 false,当读到 0 时,除了上面的例外情况,都设置为 true,在读到下一个非零数字时,再设置为 false,即可。
至于其它非零数字,在读到的同时,先判断是否应当输出"ling",再输出它的读法和它的单位。为了适应这个思路,单位数组 unit 应当对应从个位到亿位的单位{"","Shi","Bai", "Qian","Wan","Shi","Bai","Qian","Yi"}。这样,例如读到 10200 的 2 时,对应下标是2,它对应的单位是 unit[ str.size()-1-i ],即百。读到1234567的2时,对应下标是1,它对应的单位是 unit[str.size() -1 - i ],即十(万)。
另外一个繁琐的问题是空格的输出,除了第一个单词,其余单词之前都应该输出空格,这需要在输出非零数字及其单位时加以控制。
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
char digits[][6] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
char units[][6] = {"","Shi", "Bai", "Qian", "Wan", "Shi", "Bai", "Qian", "Yi"};
int main() {
int N;
cin >> N;
if(N == 0)
{
printf("ling");
return 0;
}
else if(N < 0)
{
printf("Fu ");
N *= -1;
}
string num = to_string(N);
bool printLing = false;
for (int i = 0; i < num.size(); ++i)
{
if(num[i] != '0')
{
if(i > 0) printf(" ");
if(printLing)
{
printf("ling ");
printLing = false;
}
printf("%s", digits[num[i] - '0']);
if(num.size() - 1 - i > 0) printf(" %s", units[num.size() - 1 - i]);
}
else
{
printLing = true;
if(num.size() - 1 - i == 4)
{
printLing = false;
printf(" Wan");
}
}
}
return 0;
}