【解题思路】
① 题目其实很简单,但是直接做起来很麻烦,因为各种特殊情况都需要单独加判断进行处理;
② 正常的解题方式可将输入的数当作字符串处理,然后从高位读向低位,但我个人觉得反过来从低位向高位进行判断反而能简单些,实际上把输入的数当作整数来处理比当作字符串处理方便很多,代码也能简化不少。
【1】数的一般读法规则
① 以“1234156789”为例,它的读法如下图:
② 可以看到我们读数都是4位1循环的,4位分别是千、百、十、个,每1循环后面都需要加上亿、万等单位(个省略)。由于题目输入数据大小不超过2000000000,也就是10位数,因此输入的数最大的位数不会超过十亿位;
③ 通过以上信息我们可以让输入的整数n每次循环时留下4位,来从右到左进行处理,写成代码如下:
for(int i=0;i<3;i++) // 最多3次即可处理完整数n { m=n%10000; // 每次处理4位数字 n/=10000; // n减去4位数字进入下一循环 }
④ 由于是从右到左进行处理,输出顺序是倒过来的,因此要先用一个字符数组 c[100] 来储存我们要输出的内容,同时,每个数字所对应的汉语拼音也需要倒序存放,写成代码如下:
char a[10][10]={"gnil ","iy ","re ","nas ","is ","uw ","uil ","iq ","ab ","uij "}; // 存放0-9的数字 char b[6][10]={"","ihs ","iab ","naiq ","naw ","iy "},c[1000]={0}; // 存放位数
【2】数的特殊读法规则
① 例如:200006000,读作二亿六千,而不是二亿零万六千,也不是二亿零六千;
① 解决办法:当每次循环处理的4位数字m为0时,不做处理。
② 例如:100000,读作十万,而不是一十万;210,读作二百一十,而不是二百十;
② 解决办法:判断m的十位数字是否是1,同时判断1左边是否还有其他数。
③ 例如:100600,读作十万零六百,而不是十零万零千六百零十零,也不是十万零零六百零零;
③ 解决办法:增加变量t1和t2,用来分别判断前置0和后置0的情况,分别处理。
以上数的特殊读法的判断在后续【参考代码】中指出。
【注意事项】
① 逆向判断时,数字和位数的拼音记得要倒过来,同时“位数”也是在“数字”前面储存的,不要搞错了;
② 多余的空格记得要去掉。
【参考代码】
#include<stdio.h> #include<string.h> int main(void) { char a[10][10]={"gnil ","iy ","re ","nas ","is ","uw ","uil ","iq ","ab ","uij "};// 倒序存放0-9 char b[6][10]={"","ihs ","iab ","naiq ","naw ","iy "},c[1000]={0};// 倒序存放个(省略)十百千万亿 int n,m,t1,t2; scanf("%d",&n); // 输入整数n for(int i=0;i<3;i++) // 3次循环,每次处理4位数字 { m=n%10000; // m为当前需要处理的4位数 n/=10000; // n为后面需要处理的数 if(m==0) // 若m为0说明整个4位数都是0,不需要处理 continue; if(i>0) // 存入万、亿等单位,当i=0时不需要输出 strcat(c,b[i+3]); t1=t2=0; // 初始化t1(判断后置0),t2(判断前置0) for(int j=0;j<4;j++) // 4次循环,处理个、十、百、千位 { if(m%10>0) { strcat(c,b[j]); // 存入十、百、千等单位 if(j!=1||m%10!=1||n>0||m/10>0) // 这里判断什么时候“一十”的“一”不需要 strcat(c,a[m%10]); // 存入1-9对应的倒序拼音 t1=1; t2=0; } else if(t1==1&&t2==0&&(m/10>0||n>0)) // 这里判断0要不要输出 { // 当t1=0时,说明此时的0是后置0,不需要输出 strcat(c,a[0]); // 当t2=1时,说明前置0已经输出过1次了,不需要重复输出 t2=1; } m/=10; } } for(int i=strlen(c)-2;i>=0;i--) // strlen(c)-1是多余的空格,需要去掉 printf("%c",c[i]); return 0; }
0.0分
4 人评分