最近看到一个笔试题,阿拉伯数字和汉字数字的互相转化,网上比较多的是python和java的实现,这里对C++的实现做了整理和改动。
要实现的功能是将正整数转成汉字数字,忽略小数部分(小数部分就是一对一的映射,也比较容易实现)。例如这几个测试用例:
18->十八
180->一百八十
20930->两万零九百三十
129809->十二万九千八百零九
200182190->二亿零一十八万二千一百九十
观察发现与一一对应的不同之处在于,我们用汉字称呼时要加上单位和省略多处零,并且每万位会循环从千开始称呼,例如:
12301230 =>一千二百三十万 一千二百三十
而不是被叫做 一千万二百万三十万 一千二百三十
实现以上功能的完整C++如下(详解见注释)
#include
#include
using namespace std;
string AA[] = { "零" ,"一","二","三","四","五","六","七","八","九","十" };
string BB[] = { "","十","百","千","万","十万","百万","千万","亿" };
string NumberToChinese1(int num){
string res = "";
string numstr = to_string(num); /* to_string函数转成字符串,可自动去掉 00123前面的00 */
int k = numstr.length();
for (int i = 0; i {
int tmp = numstr[i] - '0';// 得到每位的数字的大小
int bIndex = k - i - 1; // 得到从个位算起的位数个数
// cout</* 先处理该位数是0的情况,如果发现一位数是0,如果是在个位,或者它后面一位也是0,就不添加汉字零
比如10020,读作一万零二十,而不是 一万零零二十零 */if(0==tmp)
{ // cout<// cout<// cout</* 每万位的汉字计数规则会重复一下,例如12301230 一千二百三十万 一千二百三十,每万位的最低位不加零,但加上一个万级单位 */if (bIndex >= 4 && 0 == bIndex % 4)
res = res + BB[bIndex];/* 中间重复的0或者是0个位就跳过加零 */else if (('0' == numstr[i+1] && i-1 ) || i == numstr.length() - 1 )continue;else/* 如果不是以上情况,0对应汉字位置加个零字符 AA[0] */
res = res + AA[tmp];// cout<
} else
{ /* 对于该位数非0,正常添加对应汉字数字 */
res = res + AA[tmp];// cout</* 对于最开头会被称作十几的数字,如果除万后余两位,并且1开头,在从左数第一位的时候删掉十位的汉字一,常读作十几而不是一十几 */if ( k%4 == 2 && numstr[0] == '1' && i==0)
{
res.erase(0); /* 删掉第0个字符 */
}if (0 == bIndex % 4) /* 对于非零的位置,也要看是否是每万位,是的话要加上"万","亿" */
res = res + BB[bIndex];else
{
res = res + BB[bIndex % 4]; /* 对每万位以内的数字,每万位以内正常添加“十”,“千”,“百”的单位,即位数取4的余数对应的单位 */
}// cout<
}
}return res;
}int main(){/* int类型在C语言中占4个字bai节,即32个二进制位,-2^31~2^31-1=最大值2147483647
如需扩展的话 可用long long是双精度整数,占用8个字节,范围-1.7*10负308次方~1.7*10的308次方 */int m; while (cin >> m) /* 输入一个 int 型范围内的正整数 m */
{if (0 == m)
{cout <"零" <endl;
}else
{string ChineseStr = "";
ChineseStr = NumberToChinese1(m);cout <endl;
}
}
system("pause");return 0;
}
测试结果如下
版权声明:本文为weixin_29002209原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。