记一道评论区的题目

​ 导语 : 作为一个西电的菜鸡 , 每天只能和不超过两天的ddl较劲 , 啥也不懂 , 啥也不会. 因为家里硬盘不太够了所以把作业的代码传到博客里保存. 可以预见到的 , 遭到了真正大佬的嘲笑. 其中 , 二哥在讨论区里留下一道题目 , 我觉得还挺有意思的. 所以试着实现了一下 , 作为博客的第二篇拙作.

1.题目

​ 分析一下 , 是想实现一个小写数字到中文大写数字的转化. 那么 , 如果我们想要实现这个功能 , 首先我们要重新回顾一下中文数字的读法和英文读法的区别.

2.回顾背后的数学知识

​ 我们在小学二年级的时候就学过数字的读法 , 在初中的时候基本上了解到了英文的数字的读法.

比如对于31980 , 中文读作"三万一千九百八十" , 英文读作"tirty-one thousand and nine hundred eighty". 那么中文和英文对于数字的读法来说有什么不同呢?

​ 首先 , 我们要了解一下中文和英文当中对于数字的单位. 在中文中 , 有个 , 十 , 百 , 千 , 万 , 十万 , 百万 , 千万 , 亿 , 十亿… 在英文中 , 有1-20的不同的读法 , x0的读法 , hundred , thousand , million , billion… 通过比较我们不难发现其规律. 中文的数字单位是以四个为一循环 , 比如四位引出一个万 , 再四位引出一个亿. 而英语中是以三位为一个计数段 , 引出一个定义的单位.
1 , 000 , 000 , 000 1,000,000,000 1,000,000,000

英语国家的人看数字的方式.

10 , 0000 , 0000 10,0000,0000 10,0000,0000

中国人看数字的方式.

​ 两者相似的 , 对于比较小的位数划分的比较详细一些 , 而对于比较大的位数 , 中国人采取与小位数的单位相结合同时适度引入新单位来记录数字 , 而英语采用每三位定义一个单位的方式记录数字.

​ 对于中文来说 , 比较特殊的一点是 , 如果在数的中间有0的话习惯中间读一个"零"表示区分层次.

如 : 1023读作"一千零二十三" , 但是如果从某一位开始之后全是0的情况下则不读这个0. 而这个"零"的读法便是这个小demo最有意思的地方.

3.程序设计和算法思路

​ 通过上面对问题的回顾 , 我们大致可以想到一个思路. 将一个数字按4位为一组分隔开. 将0-9999的数实现向中文的转换 , 然后在后面加上单位即可. 比如12345 , 可以看作1,2345 , 那么第一组2345就读作"二千三百四十五" , 这里为了叙述方便 , 将中文大写数字"壹"写作了中文小写数字"一". 这一组因为最低位是个位 , 所以单位为空. 而第二组只有一个1 , 读作"一" , 它处于万位上. 所以后面加上单位"万". 所以读作"一万二千三百四十五".

​ 下面主要讨论如何将0-9999内的数字实现. 很自然的 , 我们想到模拟人来读数字的方法. 首先,我们将所读数的千位 , 百位 , 十位 , 个位存在一个整型数组里.
下 面 列 出 需 要 讨 论 的 几 种 情 况 : 1234 1 , 2 , 3 , 4 1 0 , 0 , 0 , 1 1001 1 , 0 , 0 , 1 1000 1 , 0 , 0 , 0 1110 1 , 1 , 1 , 0 0 0 , 0 , 0 , 0 下面列出需要讨论的几种情况:\\ 1234\\ 1,2,3,4\\ 1\\ 0,0,0,1\\ 1001\\ 1,0,0,1\\ 1000\\ 1,0,0,0\\ 1110\\ 1,1,1,0\\ 0\\ 0,0,0,0 下面列出需要讨论的几种情况:12341,2,3,410,0,0,110011,0,0,110001,0,0,011101,1,1,000,0,0,0
​ 首先来看第一种. 第一种读作"一千二百三十四" , 可以看到 , 我们开始读是从第0位开始读的 , 而且每一位都读到了. 这里我们可以得出对应规则 : 第0位对应单位为"千",如果不为0应将其读了数字名后加"千" , 之后类推.

​ 再看第二种 , 显然之前的三位都没有读到 , 是从第四位开始读的. 这里我们可以体会到 : 应该设置一个变量 , 我们设置为start. 我们通过start的状态确定读数的开始和停止.

​ 第三种读作"一千零一". 这里我们引出了中间读"零"的问题. 我们看到中间虽然有两个0 , 但是只读一次. 我们可以认为只读第一次出现的0. 所以这里我们引出变量firstzero , 用来确定是否为第一个0 , 只有第一个0会读.

​ 第四种读作"一千". 这里我们可以发现一个概念. 若从某位数开始全是0 , 则这个第一个0不读. 所以引入alwayszero变量 , 用来确定是否之后全是0 , 若是则不读 , 不是则读第一个0.

​ 第五种读作"一千一百一十". 如果我们带入前四条对应的规则应读作"一千一百一十零". 这是因为最后一位0也是第一个0且满足到最后全是0 , 所以会读出来. 那么我们如何解决呢? 这里我们对第三条规则做一个补充 : 只有第一个0 ,不在最后一位(个位)上 , 且之后不全为0时才读零.

​ 第六种 , 对于0来说 , 由于start是遇到非0元素才开始读 , 所以0是不会开启读数的. 因此 , 我们需要一个特别判定 : 当输入数字为0时只输入0 , 当数字非0时才按照前五条规则开始读数.

​ 了解原理之后 , 废话不多说 , 上代码.(注 : 这里代码中的print函数是预先定义的读数字的函数 , 比如print(1) , 输出一)

//输出0-9999的中文读法
void thousandmaxprint(int n) {//分离位数int bit[4] = { 0,0,0,0 };bit[0] = n / 1000;bit[1] = n % 1000 / 100;bit[2] = n % 100 / 10;bit[3] = n % 10;int start = 0;//开始状态变量,当其为1时才会开始打印int firstzero = 1;//寻找中间的第一个0,输出后会置为0int alwayszero = 1;//是否从第一个0开始全部是0//如果是0if (n == 0)print(n);else {            //如果不是0//开始遍历for (int tempcount = 0; tempcount < 4; tempcount++) {if (bit[tempcount] != 0 || tempcount == 3)//寻找到最后一位或已经遍历到最后一位start = 1;if (start) {if (bit[tempcount] != 0) {if (tempcount == 0) {print(bit[tempcount]);printf("千");}if (tempcount == 1) {print(bit[tempcount]);printf("百");}if (tempcount == 2) {print(bit[tempcount]);printf("十");}if (tempcount == 3) {print(bit[tempcount]);}}else {if (firstzero && tempcount < 3) {//如果是第一个0且不是最末位,则判断是否之后全是0.for (int i = tempcount; i < 4; i++)if (bit[i] != 0)alwayszero = 0;if (!alwayszero)//如果不是全部是0,则输出一个0且将第一个0状态置为0.print(bit[tempcount]);firstzero = 0;}}}}}
}

​ 上面的函数是重点. 当实现了上一个函数 , 下一个函数就好写多了. 下面我们写从1,0000到9999,9999的输出函数.

​ 这里需要探讨这样的问题. “一万零一十"的问题 , 什么时候会出现这个0呢? 是当万位一下的数小于1000的时候会输出这样的"零”. 同样的 , 当万位之后的部分为0时 , 则不读这个"零". 直接读作"一万".

​ 那么 , 归纳如下. 首先我们将数字分为万以下和万以上的部分
10 , 1234 10,1234 10,1234
​ 如果万位以上数字不为0 , 对于万以上的单位 , 读出后加上"万"字.

​ 然后对于万以后的部分 , 如果它不等于0的话 , 进一步进行判断. 若它小于1000 , 则输出"零"后再读这部分数 , 否则直接读出这部分数. 代码如下.

void tenthousandmaxprint(int n) {int n1 = n / 10000;int n2 = n % 10000;if (n1 != 0) {thousandmaxprint(n1);printf("万");}if (n2 != 0) {if (n2 < 1000);printf("零");thousandmaxprint(n2);}
}

​ 对于一亿到一万亿之间的数 , 方法和读万的方法基本是一致的. 上代码.

void hundredbillionmaxprint(int n) {int n1 = n / 100000000;int n2 = n % 100000000;thousandmaxprint(n1);printf("亿");if (n2 != 0)tenthousandmaxprint(n2);
}

​ 这就是这个程序的大概思路了. 还是比较清晰的 , 当然有的地方因为我的文笔问题可能会语义不清 , 但是我都能写出来的东西. 我相信大家一定都能写出来.

​ 最后奉上黏贴可运行的代码.

#include<stdio.h>/*
print函数负责打印0到9的中文大写.
thousandmaxprint实现不超过一万的数的中文输出.
tenthousandmaxprint实现不超过一亿的数的中文输出.
hundredbillionmaxprint实现不超过一万亿的中文输出.
日常用到中文输出的大部分是财务系统的账目大写,一般
不会超过一万亿.
*/
void print(int n);
void thousandmaxprint(int n);
void tenthousandmaxprint(int n);
void hundredbillionmaxprint(int n);/*
主程序.
*/
int main() {int n;printf("输入一个数字的小写后回车可以输出中文写法\n");scanf("%d", &n);if (n >= 100000000)hundredbillionmaxprint(n);else{if (n >= 10000)tenthousandmaxprint(n);elsethousandmaxprint(n);}return 0;
}void print(int n) {if (n == 0)printf("零");if (n == 1)printf("一");if (n == 2)printf("二");if (n == 3)printf("三");if (n == 4)printf("四");if (n == 5)printf("五");if (n == 6)printf("六");if (n == 7)printf("七");if (n == 8)printf("八");if (n == 9)printf("九");
}void thousandmaxprint(int n) {int bit[4] = { 0,0,0,0 };bit[0] = n / 1000;bit[1] = n % 1000 / 100;bit[2] = n % 100 / 10;bit[3] = n % 10;int start = 0;//开始状态变量,当其为1时才会开始打印int firstzero = 1;//寻找中间的第一个0,输出后会置为0int alwayszero = 1;//是否从第一个0开始全部是0//如果是0if (n == 0)print(n);else {//开始遍历for (int tempcount = 0; tempcount < 4; tempcount++) {if (bit[tempcount] != 0 || tempcount == 3)//寻找到最后一位或已经遍历到最后一位start = 1;if (start) {if (bit[tempcount] != 0) {if (tempcount == 0) {print(bit[tempcount]);printf("千");}if (tempcount == 1) {print(bit[tempcount]);printf("百");}if (tempcount == 2) {print(bit[tempcount]);printf("十");}if (tempcount == 3) {print(bit[tempcount]);}}else {if (firstzero && tempcount < 3) {//如果是第一个0且不是最末位,则判断是否之后全是0.for (int i = tempcount; i < 4; i++)if (bit[i] != 0)alwayszero = 0;if (!alwayszero)//如果不是全部是0,则输出一个0且将第一个0状态置为0.print(bit[tempcount]);firstzero = 0;}}}}}
}/*
分离万以上和万以下的部分应用上面定义好的函数.
*/
void tenthousandmaxprint(int n) {int n1 = n / 10000;int n2 = n % 10000;if (n1 != 0) {thousandmaxprint(n1);printf("万");}if (n2 != 0) {if (n2 < 1000);printf("零");thousandmaxprint(n2);}
}
/*
原理基本同上.
*/
void hundredbillionmaxprint(int n) {int n1 = n / 100000000;int n2 = n % 100000000;thousandmaxprint(n1);printf("亿");if (n2 != 0)tenthousandmaxprint(n2);
}

运行结果

后记

​ 完成以后在CSDN查了一下 , 发现这样的代码有很多 , 可能不是最聪明的方法 , 但希望是最能令我这种"蠢人"理解的方法.

阿拉伯数字转换成中文读法的C语言程序相关推荐

  1. js将阿拉伯数字转换成中文的大写数字

    js将阿拉伯数字转换成中文的大写数字 export const numberToChinese = (num) => {var AA = new Array("零", &qu ...

  2. python练习题--阿拉伯数字转换成中文数字

    python练习题–阿拉伯数字转换成中文数字 用户输入任意阿拉伯数字,如[123456],把它转换成中文数字[壹拾贰万叁仟肆佰伍拾陆] 以前面试时面试官问的问题,当时没能答出来,今天初步解决,把它记录 ...

  3. 【工具封装】Python 实现将阿拉伯数字 === 转换成中文大写数字

    一.序言:   工具封装第四弹,阿拉伯数字 ===> 转换成 ===> 中文大写数字,喜欢就赶紧收藏+点赞+关注吧 !!! ---- Nick.Peng 二.实现代码如下: #!/usr/ ...

  4. 将一组阿拉伯数字转换成中文大写数字

    题目大概:  将一组阿拉伯数字转换成中文大写数字  52306 ==> 伍万贰千叁百零陆 我实现了将文件中的一组数字(每行为一个数)  形如: Java代码   25364 466932300 ...

  5. java练习:金额转换,阿拉伯数字转换成中文传统形式

    需求:金额转换,阿拉伯数字转换成中文传统形式   ,例如 101000001010   转为     壹仟零壹拾亿零壹仟零壹拾圆整 最终版: import java.util.Scanner; pub ...

  6. 阿拉伯数字小写金额转换成中文大写金C额程序说明

    阿拉伯数字小写金额转换成中文大写金额C程序说明 1.问题的提出 寒假帮同学交缴话费时,不经意间看到收据上同时有小写金额和大写金额,想想各种各样的票据诸如缴费收据.银行业务回单.商场销售凭证.专用发票等 ...

  7. 将阿拉伯数字转换成中文大写金额的形式

    问题:编写控制台程序,用户输入阿拉伯数字的金额,系统自动转换成中文大写金额的形式输出. 例如:输入458796: 转换为:肆拾伍万捌仟柒佰玖拾陆. 问题分析:既然是数字大小写转换,那么我们这样考虑问题 ...

  8. 阿拉伯数字转换成中文算法--计数单位

    今天继续看<算法的乐趣>,学习了阿拉伯数字与中文数字的转化. 汉字用零一二三四五六七八九作为基本计数,与阿拉伯数字靠数字偏移位置的权位不一样,中文数字是才有"数字+权位" ...

  9. 阿拉伯数字转换成中文或中文大写

    第一种,数字转换成中文,在网上查的版本比如13,转换完成就变成一十三,非常之苦恼,经过我的一番搜查之后,发现在这个JS写的很完美,所以收藏以备后用! 先上效果图(不会显示一十三哦) 直接上代码,转载过 ...

最新文章

  1. linux c glob使用(文件路径模式查找函数)
  2. AC日记——斗地主(dfs)
  3. CentOS-创建yum本地源
  4. OpenCV使用Laplacian filtering和距离变换以及Laplacian滤波对重叠对象进行分段的实例(附完整代码)
  5. pythonxml解析拿到控件坐标_Python解析xml中dom元素的方法
  6. 周末直播丨细致入微 - OEM Grid Control 配置部署与使用
  7. ssh 协议 java_java代码之SSH协议连接linux
  8. 贪心/思维题 UVA 11292 The Dragon of Loowater
  9. 数字信号处理课程设计---带通滤波器的设计及其matlab实,数字信号处理课程设计---带通滤波器的设计及其MATLAB实现...
  10. MATLAB自学教程一1.显示图像图像基本信息
  11. PS调出唯美紫蓝色天空背景女生照片
  12. Arduino下的marlin固件配置基础
  13. 工作表冻结前两行_冻结所有工作表宏
  14. 原创 | 不瞒你说,我也参加过培训
  15. 计算机一级选择题答题技巧,计算机一级考试模拟题内容 答题技巧
  16. 诛仙斩龙墨雪服务器怎么找不到了,《诛仙3》5月13日服务器数据互通公告
  17. 关于人工神经网络的论文,人工神经网络参考文献
  18. xp系统打印机没有服务器属性设置,xp系统打印机纸张设置的方法
  19. 服务器pg信号指的是什么信号,什么是PG信号?PG信号是怎么形成的?PG信号的作用?...
  20. CobaltStrike优质学习资源

热门文章

  1. java计算机毕业设计基于安卓Android/微信小程序的大学生学习激励系统APP
  2. windows xp实用技术50招
  3. 交换机登录方式(串口方式)
  4. flink java flatMap 使用java8 lambda写法
  5. SOC | 四种 SOC修正算法
  6. ACM练级日志:“不作死就不会死” --HDU 4283 4284
  7. 《信息化项目文档模板九——系统推广方案模板》
  8. 只要我能跑,没什么不能解决
  9. Java 小数与百分数互相转换
  10. 量子计算机,开启中国速度比人类历史上第一台电子管计算机和晶体管计算机运行速度快10—100倍...