0%

PTA1082 Read Number in Chinese

题目:

Given an integer with no more than 9 digits, you are supposed to read it in the traditional Chinese way. Output Fu first if it is negative. For example, -123456789 is read as Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu. Note: zero (ling) must be handled correctly according to the Chinese tradition. For example, 100800 is yi Shi Wan ling ba Bai.

Sample Input 1:

1
-123456789

Sample Output 1:

1
Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu

Sample Input 2:

1
100800

Sample Output 2:

1
yi Shi Wan ling ba Bai

思路:

可以按每四位来组织数字段,每个数字段有一个后缀,比如1-4位后缀为“”,5-8位后缀为“Wan”,9位后缀为“Yi”,每个数字段单独组织语言,如果数字段不全为0则加上相应后缀。每个数字段负责构造一个堆栈,栈顶为高位数字的对应字符串。、

0的处理:0的出现有以下几种情况

  • 高位0,比如0123,在栈顶加“ling”。
  • 中间0,比如1203,在栈的中间位置加“ling”。
  • 低位0,比如1230,不加。
  • 全0,堆栈只有一个元素“ling”。

将几个数字段的堆栈拼接为一个堆栈,栈顶为高位数字。
注意,还要对0进行后处理,因为之前对全0的处理方式会导致下面几个问题:

  • 0重复,比如1-0000-0100
  • 出现低位上0,比如1000-0000

因此,最后还要去除堆栈中重复的零,和栈底的零;

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void print(const string& s) {
static bool first = true;
if (first) first = false;
else cout << ' ';
cout << s;
}
int main() {
string num;
vector<string> ds{ "ling","yi","er","san","si","wu","liu","qi","ba","jiu" };
vector<string> name1{"", " Shi"," Bai"," Qian" };
vector<string> name2{"", " Wan"," Yi" };
cin >> num;
vector<vector<string>> stack(3);
if (num=="0") {
cout << "ling";
return 0;
}
if (num[0] == '-') {
print("Fu");
num.erase(num.begin());
}
reverse(num.begin(), num.end());
for (int i=0; i<num.size()/4+(num.size()%4?1:0); i++) {
for (int j = i * 4; j < num.size() && j < (i + 1) * 4; j++) {
string temp;
if (num[j] == '0') {
if (!stack[i].empty() && stack[i].back() != "ling" && stack[i].back() != "Wan") stack[i].push_back("ling");
continue;
}
temp += ds[num[j] - '0'];
temp += name1[j % 4];
stack[i].push_back(temp);
}
//如果全零
if (stack.empty()) stack[i].push_back("ling");
//不全零,则在栈底加上后缀
else stack[i].front() += name2[i];
}
vector<string> s;
for (int i = 0; i < 3; i++) {
s.insert(s.end(),stack[i].begin(), stack[i].end());
}
for (auto it = s.begin(); it < s.end() - 1;) {
if (*it == "ling" && *(it + 1) == "ling") it = s.erase(it);
it++;
}
for (auto it = s.begin(); it < s.end();) {
if (*it == "ling") it = s.erase(it);
else break;
}
while (!s.empty()) {
print(s.back());
s.pop_back();
}
}

这个方法比较简洁,并且可拓展性比较强,当题目的位数限制提高后也能适用