有次在百度的面试中遇到了这个问题,当时做的比较挫,现在仔细想了一下然后写了这样的一段代码。我是按照人对数字的分析来写的这段代码。
首先,如果在数字中有小数部分,那么直接从末尾开始将小数部分的每一位转换为中文,即代码20-28行所示,最后需要增加一个“点”字。然后,从小数点左边的低位到高位四位四位地进行转换,如代码34-51行所示。flag是0位数的计数,如果当前四位全是0那么不需要每四位的单位,如”萬”,”億”,”兆”等,见52-53行。如果当前四位右边紧接着的几个位是零,那么视需要添加一个零,例如10001写作壹萬零壹,见代码37-38行。如果当前四个位中有一个或连续几个零,需要添加一个零,见39-40行,例如1001写作壹仟零壹。47-48行的代码是处理但个“0”的情况。还有一种情况比较特殊,就是有10这种情况,并不是写作“数+位”的形式,这种情况只考虑这个“拾”在最高位的情况,见代码43-45行。最后,每个四位组合在一起,转换就完成了!
#include <iostream>
#include <stack>
#include <string>
using namespace std;
string convert(string str)
{
const char *shi[] = {
"", "拾", "佰", "仟",
};
const char *wan[] = {
"", "萬", "億", "兆", "京", "垓", "秭", "穰", "沟", "涧",
"正", "载",
};
const char *number[] = {
"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖",
};
string result = "";
size_t d_pos = str.find('.');
if (string::npos != d_pos) {
for (size_t i = str.length() - 1; i > d_pos; i--) {
result = number[str[i]-'0'] + result;
}
result = "点" + result;
} else {
d_pos = str.length();
}
size_t i = d_pos, len = str.length(), four = 0, flag = 0;
for (string temp, appd; i; four++, result = temp + appd + result) {
temp = "";
appd = "";
for (int one = 0; i && one < 4; one++, i--) {
int ch = str[i-1] - '0';
if (ch) {
if (flag > one && i + flag != d_pos)
appd = number[0];
if (flag > 0 && flag < one)
temp = number[0] + temp;
flag = 0;
temp = shi[one] + temp;
if (ch != 1 || one != 1 || i != 1) {
temp = number[ch] + temp;
}
} else {
if (len == 1)
appd = number[0];
flag++;
}
}
if (flag < 4)
temp = temp + wan[four];
}
return result;
}
int main(int argc, char *argv[])
{
if (argc != 2) {
cout << "usage : " << argv[0] << " num" << endl;
return -1;
}
cout << convert(argv[1]) << endl;
return 0;
}