可怜的小凡

小凡的老师给了小凡一个任务就是做一个中文的计算器。比如说输入“十加十”,那么小凡就要得到 20 这个值
,但是小凡太笨怎么都搞不定,所以老师给他降低了要求,让他只要把阿拉伯数字转换成中文就行了,
还说如果他连这个都不会就不给他及格了。小凡都快哭了,好心的你帮帮他吧。
输入
有多组测试数据,请用while(…)读入数据,直到EOF。
每组数据为一串数字,如:2358298951(不超过9999)。
输出
每个输入对应一个输出。对应上面的输出分别为二千三百五十八、两千九百八十九、五十一。
样例输入
36
211
2126
10
20
101
样例输出
三十六
二百一十一
二千一百二十六
二十
一百零一
提示
1、用while(scanf(“%s”,str)!=EOF)或while(gets(str)//返回值与NULL比较)循环读取每组数据。
2、情况比较繁琐,请多思考
//策略:
1.梳理一下如果是人类来识别阿拉伯数字并转化为中文的过程:
a.先数出这个数是几位数,以便确定最高位;
b.如果数码不是0,则连同他的权一起读出来;如果遇到数码为零的则该为的权就不读出来;
(一个零我们直接读个零;如果有多个相邻的零,我们也只读一个零) (这一条规则是本题的处理的关键,
看看能否在这点转化,优化算法)
//为了监测是否有相邻的零存在,我们可考虑设一个监控变量flag(相邻零的个数):
当flag = 1 且不超过1:不读出它的权(屏蔽掉该位的权);当flag = 2时,屏蔽掉前一个零(考虑写成函数)
迭代上述过程.(最终没有采用该法.)
思想方法,变换角度审视问题(经常是在构成问题的这些素材之间切换视角)
比如100101
十万位上有非0数,我们就连同它的权读出,下一个非零数为百位,也连同它的权一起读出,
再有个位上的非零数(这时只读出数码) 一十万 一百 一
再往里头插入一个零,如果有空位的话。(想法挺好,不太好实现.最后还是边调用函数(处理非零) 便插入'零'一个比较长的if)
好在这个题目要求的范围只在9999内,不会引起十万和一十万的分歧(然而11读十一还是一十一)
即便有如此分歧,我们可以单独再开一一个if 输入的如果是两位数且以一开头。判断即可(单独一个:0)
*/
```c
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
//在此下方插入自定义函数对的声明:
/* 阿拉伯数字转换为汉字. */
char * change_to_Chinese_character(char str_i, char*);
/* 权重函数 */
char* insert_weights(char *buf, int len);
//void insert_zero(char(*b)[6];
int internal_zero(char *str,int i,int len);/* 处理内部和外部(尾端的一些零) */
//主函数main
int main()
{
//printf("test:\n");
char str[5];/* 读入的阿拉伯数子不超过9999 ,但可以自行增加字典*/
char buf[10];/* 用来带回函数处理后字符串.在函数调用时,它会被清空之前的残留,进行该次重写 */
//int len = strlen(str);还未读入内容!应在scanf之后
while (scanf("%s", str) != EOF)
{
//char str[5];/* 读入的阿拉伯数子不超过9999 */
/* 将读入的数字字符串转化为数码,并存储到整形数组中去,方便提供运算。 */
int len = strlen(str);
/* int number[5];
for (int i = 0; i<len; i++)
{
number[i] = str[i] - '0';
}*/
char result[10][6] = { 0 };/* */
int cnt_result = 0;
if (str[0] != '0')//len != 1 &&
{
int k = 0; /*用于指示移位填充*/
int j = len; /*是否打印出来是另一回事,权始终是要向后移动的*/
for (int i = 0; i < len; i++) /* 需要测试len次. */
{
/* k比较灵活,用于指引strcpy()填充内容到result中位置 */
if (i >= 1 && str[i] == '0' && str[i - 1] != '0' && internal_zero(str, i, len))
{
strcpy(result[k++], change_to_Chinese_character(str[i], buf)); //至少要等到k = 2之后
cnt_result++;
}
else if (str[i] != '0')
{
/* 这个手法很好,在把当前位置填充后,还把位置指向下一个,放置冲突 */
strcpy(result[k++], change_to_Chinese_character(str[i], buf)); /* 一个汉字就是一个字符串 */
cnt_result++;
if (j >= 2)
{
strcpy(result[k++], insert_weights(buf, j));
cnt_result++;
}
}
j--;
}
}
else
{
strcpy(result[0],"零") ;
cnt_result++;
}
//int delta[5];
//int j = 0;
//for (int i = 0; i < len; i++)
//{
// if (str[i] == '0')
// {
// delta[j++] = i;
// }
//}
// int cnt = 0;/* 记录len中有多少字符串.(单独计数不太方便(就在写入result的时候顺便给它计数))
// 如果是要单独计数,可以考虑在使用result之前(定义的同时,将其初始化掉),
// 利用strlen,更好是strcmp() */
// for( int i = 0 ;i < len;i++ )
// {
// strcpy(result[i],change_to_Chinese_character(str[i],buf));
// cnt++;
// }
for (int i = 0; i < cnt_result; i++)
{
if (len == 2 && str[0] == '1')
printf("%s", result[i + 1]);
else
printf("%s", result[i]);
}
printf("\n");
}
return 0;
}
//主函数结束
//在下方编写自定义函数:
int internal_zero(char *str,int i,int len)
{
int cnt = 0;
for(;i<len;i++)
{
if(str[i] != '0')
{
cnt++;
}
}
/* if(cnt>0)
{
return 1;
}else
{
return 0;
}
*/
return cnt;
}
/* 考虑在主函数中联合判断控制流交叉调用. */
/* 一旦调用,就打印最高位,调用条件位len >= 2 并且当前位的数码非零,(利用迭代j=len来实现重复利用.) */
char* insert_weights(char *buf, int len)
{
char weight[5][6] = { "十","百","千", "万" };//这个东西不太灵活,就放在函数里定义即可.
strcpy(buf, weight[len - 2]);//weight[strlen(a) - 2 - i] 列地址.
return buf;
}
char * change_to_Chinese_character(char str_i, char* buf)
{
/* 用gcc编译一个程序的时候出现这样的警告:
warning: control reaches end of non-void function
它的意思是:控制到达非void函数的结尾。
就是说你的一些本应带有返回值的函数到达结尾后可能并没有返回任何值。
这时候,最好检查一下是否每个控制流都会有返回值 */
switch (str_i)
{
case '1':
strcpy(buf, "一");
break;
case '2':
strcpy(buf, "二");
break;
case '3':
strcpy(buf, "三");
break;
case '4':
strcpy(buf, "四");
break;
case '5':
strcpy(buf, "五");
break;
case '6':
strcpy(buf, "六");
break;
case '7':
strcpy(buf, "七");
break;
case '8':
strcpy(buf, "八");
break;
case '9':
strcpy(buf, "九");
break;
case '0':
strcpy(buf, "零");
break;
default:
break;
}
return buf;
}
posted @   xuchaoxin1375  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示