本题稍难,如果没有思路,请顺序认真阅读本文!(全网最全最详细题目解析)
预备知识:
C/C++string头文件使用方法——PAT常用知识点(一)
- < string >头文件函数:substr(pos, len) 返回从pos号位开始,长度为len的子串。
题目翻译:
给定一个不超过9位数的整数,你需要用传统中文方式将它读取。如果是负数,首先输出 “负” 。例如,“-123456789” 读作 “一亿两千三百四十五万六千七百八十九”。注意:根据中文数字的读法,零(0)必须要被正确的处理。例如,“100800” 是读作 “一十万零八百”。
难点单词:
supposed to 应该
according to 据 ; 按 ; 依照 ; 按照 ; 根据
输入格式:
每个输入文件包含一个测试用例,它将给出一个不超过9位的整数。
输出格式:
对于每个测试用例,在一行中打印数字的中文阅读方式。字符之间用空格隔开,行尾不能有多余的空格。
输入样例(一):
-123456789
输出样例(一):
Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu
输入样例(二):
100800
输出样例(二):
yi Shi Wan ling ba Bai
题目解析:
字符串处理题,较难,有很多分支逻辑需要处理。
首先可以自己列举一些输出结果,找找所有数的共同点。可以发现:
- 除个位外,所有非零位在输出的时候都是先输出大写数字(如 “五” )再输出大写位(如 “千” )的形式;
(非零位的数字和位同时输出) - 若当前剩余数字为个数为4的倍数位,不论当前位是否为零,都要输出当前位单位(如 “万”、“亿” );
(每隔4位必定输出一个位单位) - 若万级上存在连续4个0,不能读万只能读零,如 “1,0000,2345” ,读作 “一亿零两千三百四十五”。(此种情况需要结合情况2进行特殊处理)
- 两个以上连续的0,最多只能读一次,如 “1002” ,读作 “一千零二”;
- 若某一个0位于万级,需要读出来,如 “10,0005” ,读作 “十万零五”;
逻辑梳理:
逻辑梳理非常重要!请务必先自己梳理一遍完整流程再看解析和代码!
若输入数据为0的话需要进行特判。当输入的数据不为0时:
-
若有符号,首先需要输出符号,然后将符号从数串中删除(方便后续处理);
-
从第一位数(最高位)开始检查。每一位数都会出现两种情况:①当前位非0 ②当前位为0(显然最高位不会为0);
-
若当前位非0
a. 若当前位的前一位(或几位)为0,不论前面有几个0(显然这里需要一个变量来记录连续0的个数),都只用输出一个0,然后输出当前位的大写数字和大写位。b. 若当前位的前一位非0,直接输出当前位的大写数和大写位。
-
若当前位为0,累加连续0的个数,然后判断当前0的个数是否达到了上面分析的那个特殊条件「若万级上存在连续4个0,不能读万,只能读零」,若成立,则输出当前位的大写,然后将连续0个数重制为0。
-
看到这里,你可能有点懵。没关系,自己在纸上多分析一下处理流程。
建议先根据自己对上面的理解分析写出自己的代码再往下看~
参考代码:
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
string units[9] = {"", " Shi", " Bai", " Qian", " Wan", " Shi", " Bai", " Qian", " Yi"};
string nums[10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
string number;
cin >> number;
if ( number == "0" ) { // 输入为0特判
cout << "ling" << endl;
}
else { // 输入不为0
if ( number[0] == '-' ) { // 先输出符号
cout << "Fu ";
number = number.substr(1); // 输出后从字符串中删除
}
int len = number.length(); // 数字的个数
int gap = 0; // 两个非0数字间0的个数
for (int i = 1; i <= len; i++) {
int n = number[i-1] - '0';
if(n != 0) {
if(gap) {
cout << " ling";
gap = 0;
}
if(i > 1) cout << " ";
cout << nums[n] << units[len-i];
} else {
gap++;
// 若未处理的数字个数为4的倍数且非连续4个零
if((len-i)%4 == 0 && gap%4 != 0) {
cout << units[len-i];
gap = 0;
}
}
}
}
return 0;
}
全部通过
我知道,本道题可能会有点难。
但别灰心!要知道我都分析了两个多小时才弄明白【哭笑
一起加油!