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. 萬以上要取餘,但是萬位、億位要保留。