18->十八
180->一百八十
203->两百零三
8008->八千零八
20930->两万零九百三十
3209809->三百二十万九千八百零九
40029302->四千零二万九千三百零二
200182190->二亿零一十八万二千一百九十
说明:2读作“二”,输入最大到亿
本代码没有小数功能
笔试遇到的,网上很多博客都是用java写的,本博客用C++实现,写的时候磕磕绊绊,对于各种情况的0处理不好,参考其他博主的java实现方式,并结合自己直观的想法,实现如下:
string AA[] = { "零" ,"一","二","三","四","五","六","七","八","九","十" };
string BB[] = { "","十","百","千","万","十万","百万","千万","亿" };
//对于10023209会输出"一千万零二万三千二百零九",错误
//应该输出"一千零二万三千二百零九"
string NumberToChinese1(int num)
{
string res = "";
string numstr = to_string(num); //直接把00123这种前面的0去掉了
int k = numstr.length();
for (int i = 0; i<numstr.length(); i++)
{
int tmp = numstr[i] - '0';
if (0 == tmp)
{
if ('0' == numstr[i - 1] || i == numstr.length() - 1)
continue;
else
res = res + AA[tmp];
}
else
{
res = res + AA[tmp];
if (numstr.length() == 2 && numstr[0] == '1' && i == 0)
{
res.erase(0); //12读作十二,把1删掉
}
res = res + BB[k - i - 1];
}
}
return res;
}
以上NumberToChinese1实现方式大部分情况都是正确的,但是有一个问题就是对于万位以上会连着出现“百万十万”的现象,比如10023209会输出“一千万零二万三千二百零九”,这是错误的。事实上,我们在读数的时候,是四位四位读的,所以应该引入%4,改进后的完整代码为:
#include<iostream>
#include<string>
using namespace std;
string AA[] = { "零" ,"一","二","三","四","五","六","七","八","九","十" };
string BB[] = { "","十","百","千","万","十万","百万","千万","亿" };
string NumberToChinese(int num)
{
string res = "";
string numstr = to_string(num); //直接把00123这种前面的0去掉了
int k = numstr.length();
for (int i = 0; i<numstr.length(); i++)
{
int tmp = numstr[i] - '0';
int bIndex = k - i - 1;
if (0 == tmp)
{
if ('0' == numstr[i - 1] || i == numstr.length() - 1)//处理2003、230出现多余的零
continue;
else if(bIndex >= 4 && 0 == bIndex % 4)//处理2103243在万位出现多余的零
res = res + BB[bIndex];
else
res = res + AA[tmp];//正常零
}
else
{
res = res + AA[tmp];
if (numstr.length() == 2 && numstr[0] == '1' && i == 0)
{
res.erase(0); //12读作十二,把1删掉
}
if (0 == bIndex % 4)//万、亿位的要输出
res = res + BB[bIndex];
else
{//"十万","百万","千万"其实就是一摆设,万不输出
res = res + BB[bIndex % 4];
}
}
}
return res;
}
int main()
{
int m;
// cin >> m;
while (cin >> m)
{
if (0 == m)
{
cout << "零" << endl;
}
else
{
string ChineseStr = "";
ChineseStr = NumberToChinese(m);
cout << ChineseStr << endl;
}
}
return 0;
}
运行结果如下:
总结本题难点:
1. 18读作十八,前面的1不读;而28读作二十八。
2. 230读作二百三十,结尾的0不读。
3. 类似2003这种出现连续多个零,只读一个零。
4. 万以上要取余,但是万位、亿位要保留。