数的读法c语言程序,[蓝桥杯]数的读法-笨办法(C语言)

## 解题思路

先不考虑细枝末节,读几个数字可以发现,中文读法是从个位数字开始,每**四个**数字为一组来读的:如 25694123 读作 (二亿)(五千六百九十四万)(四千一百二十三)每一组都可以看作是:

几千几百几十几 + 亿/万/(空)整体思路便是将输入的数字(最多11位)分成三组,如图所示:

![](/image_editor_upload/20191107015834_49555.png)

每一块从左到右分别命名为“千”,“百”,“个”,“十”

一共需要3x4=12个容纳数字的空间,为了方便处理我们以字符串的形式输入,给'\0'腾出一个空间,所以创建字符数组:

```c

char num[13]; //字符数组

```

为了将数组的下标与“千”,“百”等单位更好地联系起来,我们将数字整体移动到数组的“尾部”,移动后'\0'在num[12]处。

![](/image_editor_upload/20191107011526_90473.png)

这样,亿级别的四位数对应num[0]~num[3]

万级别的四位数对应num[4]~num[7]

最后的四位数对应的是num[8]~num[11]

同样的,每一组的“千”对应的下标是0,4,8

“百”对应的是1,5,9

.......

可以发现,只要给定下标,就能确定其“级别”(亿,万)以及“单位”(千,百,个,十):

确定级别,只需用下标sub/4,如果为0,则是亿级别,为1,是万级别,为2,则是个级别

确定单位,只需用下标sub%4,如果为0,则是每组的“千”为,为1,则是“百位”,以此类推。

接下来则只用遍历这个字符数组,对每一个字符的下标进行“除4”和“余4”的操作,结合他本身的值便能读出 数值+单位 的组合

光做到这些也远远不够,有非常多的细节需要去考虑:

①“一十”与“十”

前者是 数值+单位 的组合,后者是仅仅只有单位。1010读作** 一千零一十** 而 100000 读作**十万**,而并非 一十万。我们发现,如果1是处在这个数字的最开始,且位于某组的十位时,那个 一 是不用读的,而对于不处于数字最开始位置的十位 一 是需要读成 一十的

②零的读法

可以说是这道题相对来说最困难的点

首先,每组个位的0是不读的,这点很好实现

其次,多个0连续的问题,多个0连续只读一次,或者不读,如10011000,前四个数字读成 一千零一万 连续的零读一次 后四个数字读成一千 连续的三个零一个都不读

究其原因,第一组中连续的零后面还有一个不为0的1,而第二组中后面三位数全部是0.所以确定0到底怎么读的具体思路是:

**读到0--从这个0开始扫描到这一组的末尾----设读0标志位为1(表示已经读了一次0)--读下一位--**

这样便能正确的读出数字中的0了

③“亿”和“万”读法

随便举个数字我们可以发现,“亿”是跟在第一组的个位后面的,而“万”是跟在第二组的个位后面的,比如,1500649302 读作一(第一组个位)**亿**五千零六(第二组个位)**万**九千三百零二(最后一组的个位后面不跟任何单位)

但有些情况,亿和万又不需要读,如100000000,中的万就没有读,是因为第二组为0000,全是0,所以不读,哪怕是0001,都要读成零一万,所以只需判断某组是否全为0即可。

细节考虑大概就这些,下面贴代码,写的不是太好,感觉有点复杂化了:

```c

#include#include#define size 13

int main()

{

int i,j,k,flag; //flag为读0标志位

char num[size]; //长度为13的字符串数组

scanf("%s",&num);

int length = strlen(num); //数字组的长度

int move_step , first_sub;

int info1 , info2; //第一个判断个十百千

int cz;

char c;

char *unit[3] = {"qian","bai","shi"};

char *bigunit[2] = {"yi","wan"};

char *a[10] = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};

/*整体移动数字到末尾*/

move_step = (size - 1) - length; //需要移动的步长

for(i = length ; i >= 0 ; i--)

{

num[i + move_step] = num[i];

num[i] = 0; //前面的空格取为0

}

/*开始从左到右遍历字符串*/

first_sub = move_step; //此时第一个元素的下标

flag = 0;

for(i = first_sub; i < size - 1 ; i++)

{

info1 = i%4;

info2 = i/4;

c = num[i];

cz = c - '0'; //c对应的整形值

/*info1 为0对应qian 1对应bai 2对应shi 3对应个位

info2 为0 个位处打印亿 为1 打印万*/

if(c != '0') {flag = 0;}

if(i == first_sub && info1 == 2 && c == '1')

printf("%s ", unit[2]); //开头十位的1不读 如100000读作十万而不是一十万

else if(c == '0' && info1 == 1 && (num[i + 1] != '0' || num[i + 2] != '0') && flag == 0) //flag为0接收读0

{ printf("%s ", a[cz]); flag = 1;}

else if(c == '0' && info1 == 2 && num[i + 1] != '0' && flag == 0) //flag为0接收读0

{ printf("%s ", a[cz]); flag = 1;}

else if(c == '0' && info1 == 0 && (num[i + 1] != '0' || num[i + 2] != '0' || num[i + 3] != '0') && flag == 0) //flag为0接收读0

{ printf("%s ", a[cz]); flag = 1;}

else if(c == '0' && length == 1) //单独输入为0的时候

{ printf("%s ",a[cz]);}

else if(info1 == 3) //个位

{

if(c == '0' && info2 == 0) //亿级别

printf("%s ", bigunit[info2]); //此时零不读 info2是0 打印yi

else if(c != '0' && info2 == 0)

printf("%s %s ", a[cz], bigunit[info2]);

if(c == '0' && info2 == 1 && (num[i - 1] != '0' || num[i - 2] != '0' || num[i - 3] != '0')) //万级别

printf("%s ", bigunit[info2]); //此时零不读 info2是1 打印wan

else if(c != '0' && info2 == 1)

printf("%s %s ", a[cz], bigunit[info2]);

else

;

if(c == '0' && info2 == 2)

printf("");

else if(c != '0' && info2 == 2)

printf("%s ",a[cz]); //此时个位后面不需要带什么单位

}

else if(c != '0')

printf("%s %s ",a[cz],unit[info1]);

}

return 0;

}

```

ac是没什么问题的,但是line9那里从键盘接收字符我最开始用的gets()函数,死活都过不了,显示答案错误12%

但改成scanf之后就过了,求哪位大佬评论区解答一下。。

0.0分

6 人评分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值