数字->中文计数法 (C语言编写)
1.功能简介
主要功能为将亿以内的整型数据转化成中文形式的计数方法,如可将666转化为六百六十六,6666转化为六千六百六十六,66666转化为六万六千六百六十六,以此类推。
2.代码行数
有效代码约170行左右。
3.实现步骤
由简单到复杂逐步实现。
-
首先实现万以内的转化,再推广到亿以内
- 首先实现对单个数位的分离和转换
也即将666转化为六六六 - 然后给每个数后面加上单位
即将666转化为六百六十六
1080转化为一千零百八十零
1001转化为一千零百零十一
看起来我们已经可以对某些数实现了所需功能
接下来来考虑特殊情况- 对于1080我们不希望它出现百位的单位百
需要想办法修正 - 对于1080我们不希望它出现最后一位的零
需要想办法修正 - 对于1001我们不希望连续出现两个零
在有多个零时我们只希望它出现一个
- 首先实现对单个数位的分离和转换
-
扩展到亿以内
4.源码
#include <stdio.h>
#include <math.h>
void NumberToCharacter(int goal);
void ThousandToCharacter(int goal,int max_digitnumber_flag);
int GetDigitNumber (int goal,int max_digitnumber_flag);
void PrintNumber(int digit,int *zero_output_flag,int *unit_output_flag);
void PrintUnit(int digit_number,int unit_output_flag);
int RemoveOneDigit(int goal,int *digit_number);
int GetSingleDigit(int goal,int digit_number);
enum {NO=0,YES};
int main()
{
/*NumberToCharacter(0);
NumberToCharacter(9);
NumberToCharacter(10);
NumberToCharacter(99);
NumberToCharacter(100);
NumberToCharacter(209);
NumberToCharacter(999);
NumberToCharacter(1000);
NumberToCharacter(1001);
NumberToCharacter(1010);
NumberToCharacter(1100);
NumberToCharacter(1110);
NumberToCharacter(1111);*/
NumberToCharacter(666666);
return 0;
}
/*功能:将数字(亿以内)转化为中文计数法
参数:需要转化的数字*/
void NumberToCharacter(int goal)
{
int max_digitnumber_flag=NO;
if(goal>=1e4&&goal<1e8-1)
{
ThousandToCharacter(goal/1e4,max_digitnumber_flag);
printf("万");
max_digitnumber_flag=YES;
}
ThousandToCharacter(goal%10000,max_digitnumber_flag);
printf("\n");
}
/*功能:将数字(万以内)转化为中文计数法
参数:goal需要转化的数字
max_digitnumber_flag代表原数是否大于一万,对于中间零的判断很重要
例如数10001如果只是单纯分离可能变成“一万一”
借助该参数可变成“一万零一”*/
void ThousandToCharacter(int goal,int max_digitnumber_flag)
{
int digit;
int digit_number;
int zero_output_flag=NO;
int unit_output_flag=YES;
if(goal==0&&max_digitnumber_flag!=YES)//第二个条件注意一下
{
printf("零");
}
else
{
digit_number=GetDigitNumber(goal,max_digitnumber_flag);
while(digit_number>=0)
{
digit=GetSingleDigit(goal,digit_number);
PrintNumber(digit,&zero_output_flag,&unit_output_flag);
PrintUnit(digit_number,unit_output_flag);
goal=RemoveOneDigit(goal,&digit_number);
}
}
}
/*功能:获取目标数字最高数位的数字
参数:goal目标数字
digit_number数位的个数*/
int GetSingleDigit(int goal,int digit_number)
{
int magnitude;
magnitude=(int)(powf(10,digit_number));
return goal/magnitude;
}
/*功能:去除目标数字的最高数位
参数:goal目标数字
digit_number数位的个数*/
int RemoveOneDigit(int goal,int *digit_number)
{
int magnitude;
magnitude=(int)(powf(10,*digit_number));
(*digit_number)--;
return goal%magnitude;
}
/*功能:获取目标数字数位的个数
参数:goal目标数字
max_digitnumber_flag判断原数字是否大于等于10000*/
int GetDigitNumber (int goal,int max_digitnumber_flag)
{
int i;
int digit_number;
int magnitude;
if(max_digitnumber_flag==YES)
return 3;
else
{
for(i=0; i<4; i++)
{
magnitude=(int)powf(10,i);
if(goal/magnitude>0)
{
digit_number=i;
}
}
return digit_number;
}
}
/*功能:对单个数字进行转换
参数:digit进行转换的数字
zero_output_flag是否输出“零”的判据
unit_output_flag是否输出该数位单位的判据
注意:0单独判断*/
void PrintNumber(int digit,int *zero_output_flag,int *unit_output_flag)
{
if(digit!=0)
{
*unit_output_flag=YES;
if((*zero_output_flag)==YES)
{
printf("零");
*zero_output_flag=NO;
}
}
switch (digit)
{
case 1:
printf("一");
break;
case 2:
printf("二");
break;
case 3:
printf("三");
break;
case 4:
printf("四");
break;
case 5:
printf("五");
break;
case 6:
printf("六");
break;
case 7:
printf("七");
break;
case 8:
printf("八");
break;
case 9:
printf("九");
break;
case 0:
*zero_output_flag=YES;
*unit_output_flag=NO;
break;
}
}
/*功能:输出某个数位的单位(十/百/千,没有万)
参数:digit_number数位的个数
unit_output_flag是否输出该数位单位的判据*/
void PrintUnit(int digit_number,int unit_output_flag)
{
if(unit_output_flag==NO)
return;
else
{
switch(digit_number)
{
case 1:
printf("十");
break;
case 2:
printf("百");
break;
case 3:
printf("千");
break;
case 0:
return;
}
}
}
5.细节处理
- 最高数位的获取、去除:
利用得商除法和求余除法 - 10的n次方调用了库函数<math.h>中的powf
避免了pow函数对整数求算结果少1的问题
(powf是C99之后才有的特性) - 关于数字中连续多个数位出现0的问题:
为保证只出现一次“零”
在连续零后面第一个不为零的数出现时再输出“零”
同时需要借助一个参数控制
如:对于1001,在判定到百位时,参数变为准备输出“零”的值
判定到十位,因为位上的数为0,不满足条件,参数不变,继续向后传递
判定到个位,位上的数不为0,满足条件,先输出零,再输出一 - 当原始数字为0时,不符合规则,需要单独处理
- 关于是否输出特定数位的单位,也需要一个参数来控制
6.不足之处
- 功能不足:
两个不符合语言习惯之处- 13不会转化为十三而是一十三
- 20001不会转化为两万零一而是二万零一
二作第一个数位时不会读作两
似乎也可以接受 - 应用限制:亿以内的数据转换
主要是int最大值的限制
换成long长整型或许可以摆脱这一限制
- 代码缺陷:
- 没有对原数据进行保留,一位位去除
最后原数据未被保存 - 没有对转换成的中文字符串进行储存
只能做到转化后直接输出
- 没有对原数据进行保留,一位位去除