A1082 Read Number in Chinese [汉字读数字]
———————————————————————————
这是简单模拟中最难的一道题,我也是想了很久,这题放考场上我肯定是做不出的,最后算是看懂了,然后把思路说一下,感觉网上思路都没有说的很清楚。
思路 :
- 首先它是分字节来处理,这里的字节不是计算机中的byte,而是数字的字节,4位后是万,在4位是亿,然后从右到左每4个节处理一次,高位不足4位的就直接处理。
- 每个节内处理就是非零的数就读出相应的数字和位数,当做一个4位数字来读。
- 每读完4位数字要看这个数字是否大于5位,大于5位就最后还要读出相应的万或者亿。
- 如果有连续的0出现在非零数字之间,如100001注意只要读出一个ling。
#include<iostream>
#include<string>
using namespace std;
string num[10] = { "ling","yi","er","san","si","wu","liu","qi","ba","jiu" };
string wei[5] = { "Shi","Bai","Qian","Wan","Yi" };
int main()
{
string s;
getline(cin, s);
int length = s.length();
int left = 0, right = length - 1;
if (s[0] == '-')
{
cout << "Fu";
left++;
}
while (left + 4 <= right) //从右到左每四位为一节,按节处理,多余的直接处理
right -= 4;
while (left < length)
{
bool flag = false; //表示没有累计的0
bool isprint = false; //表示该节没有输出过其中的位(如果是个位,不用输出后面的位数)
while (left <= right)
{
if (left > 0 && s[left] == '0') //如果当前位为0
{
flag = true;
}
else //如果当前位不为0
{
if (flag == true) //存在多个累计的0 只输出一遍ling就行
{
cout << " ling";
flag = false;
}
if (left > 0)
cout << " ";
cout << num[s[left] - '0'];
isprint = true;
if (left != right) //某个节中除了个位外,都需要输出十百千
{
cout << " "<<wei[right - left - 1];
}
}
left++;
}
if (isprint && right != length - 1) //只要不是个位,输出万和亿
{
cout << " "<<wei[(length - 1 - right) / 4 + 2]; //存在一个节 输出万 存在两个节 输出亿不会超过9个数
}
right += 4;
}
return 0;
}