1082 Read Number in Chinese (25 分)
題目傳送門:1082 Read Number in Chinese (25 分)
一、題目大意
將數字按照中文讀法輸出
Sample Input 1:
-123456789
Sample Output 1:
Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu
Sample Input 2:
100800
Sample Output 2:
yi Shi Wan ling ba Bai
二、解題思路
將數字轉化爲字符串,然後按位判斷。
注意點:
- 當數字中間隔了零,無論有多少個連續的零,都只讀一次“ling”,那麼只需要判斷零與非零的臨界點處讀“ling”即可。
- 當前位下標i%4,分別對應單位“Ge”、“Shi”, “Bai”, “Qian”, 不過“Ge”不需要讀出來,所以當i%4!=0時,才需要讀單位。
- 如果當前位下標i是4,且萬位組的值不爲0,也就是n%10000000/10000不爲零時,纔讀單位“萬”。如100000007,讀作“yi Yi ling qi”,中間萬位組單位“Wan”不用讀。而104000007,要讀“yi Yi ling si Bai Wan ling qi”,需要讀中間的單位“Wan”。
- 如果當前下標i是8,且億位組的值不爲0,也就是n/100000000不爲零纔讀單位“億”。同上。
- 由於是反向存放的結果集中的,所有有單位時,要先存單位再存數值。
- 當前數值如果是零,則判斷下一位是否爲零,如果下一位不是零,則存入“ling”。
- 如果當前位不是零,則直接將當前位存入結果集。
代碼中有註釋解釋。
三、AC代碼
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<string>v1{"Ge", "Shi", "Bai", "Qian", "Wan", "Yi"};
vector<string>v2{"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
int n;
cin >> n;
if(n == 0){// 特判
cout << "ling" << endl;
return 0;
}
string s = to_string(n);
reverse(s.begin(), s.end());// 轉成字符串,低位在前面
int last = 0;
vector<string> res;// 存放結果
for(int i = 0; i < s.size(); i++){
if(s[i] == '-'){
res.push_back("Fu");// 存放
break;
}
if(i == 4 and n % 100000000 / 10000){// 補充單位 萬
res.push_back(v1[4]);
}
if(i == 8 and n / 100000000){// 補充單位 億
res.push_back(v1[5]);
}
if(s[i] == '0'){
if(i and s[i-1] != '0'){
res.push_back(v2[0]);// 在零與非零的交界處出纔讀零,連續的零只需要讀一次
}
}else{
int x = i%4;
if(x!=0){
res.push_back(v1[x]);// 存入單位 千/百/十
}
res.push_back(v2[s[i]-'0']); // 存入數值。本題對十位是1的情況保持讀yi Shi,如果十位爲1直接讀Shi,則此處還要做判斷處理
}
}
reverse(res.begin(), res.end());// 反轉過來輸出結果
for(int i = 0; i < res.size(); i++){
if(i){
cout << " " << res[i];
}else{
cout << res[i];
}
}
cout << endl;
}