【PAT甲级 - C++题解】1082 Read Number in Chinese

简介: 【PAT甲级 - C++题解】1082 Read Number in Chinese

1082 Read Number in Chinese


给定一个不超过 99 位的整数,你应该用传统的中文方式阅读它.


如果是负数,则先输出 Fu。


例如,-123456789 读作 Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu。


注意:零(ling)必须按照中国传统正确处理。


例如,100800 读作 yi Shi Wan ling ba Bai。


输入格式

共一行,包含一个不超过 99 位的整数.

输出格式

输出给定数字的中文读法,注意结尾不能有多余空格。


输入样例1:

-123456789
• 1

输出样例1:

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

输入样例2:

100800
• 1

输出样例2:

yi Shi Wan ling ba Bai


思路


这道题大致的思路是先处理最前面的正负号,然后再将剩余数字进行划分,除了最高位其它分成 4 位一组。例如, 123456789 可以划分成 1 、2345 和 6789 三组,然后再分别进行处理。


这道题需要注意的是,正常的数字转换是小写的,而涉及到亿、万、千、百和十的开头都需要大写。另外,这里涉及到了一个 c++ 的函数 stoi ,作用是将字符串类型转换成整数类型。


先处理负号情况,如果有负号就加入 ans 当中。

处理数字存在第 9 位的情况。注意,需要先判断第 9 位是否为 0 ,如果为 0 直接跳过不去处理,后面的 5~8 位和 1~4 位同理,例如 100000000 就不需要处理后面 8 位。

处理数字存在第 5~8 以及 1~4 的情况,处理函数如下:

先处理前缀 0 。

再分别处理千位、百位、十位和个位,因为数字位数不定,所以我们需要额外进行判断。

判断 flag 是否为 0 ,如果为 0 说明并没有经过步骤 2 和 3 的处理,它本身就为 0 ,直接加入 ans 即可。

如果 ans 最后有空格的话需要去除,否则官网会报格式错误,然后输出结果 ans 即可。


代码

#include<bits/stdc++.h>
using namespace std;
//数字翻译
string nums1[] = { "ling","yi","er","san","si",
                "wu","liu","qi","ba","jiu" };
string nums2[] = { "Qian ","Bai ","Shi ","" };
//为了防止出现格式错误,我们用一个字符串容器来存储答案
string ans = "";  
//处理四位数字
void work(string x)
{
    //先将处理前缀0
    int k = 0;
    while (k < x.size() && x[k] == '0')    k++;
    if (k != 0)    ans += "ling ";
    x = x.substr(k);
    int cnt = 0;  //统计目前遍历到字符串x的第几位,因为可能不是4位数,直接用i访问会越界
    int flag = 0; //处理数字中间出现0的情况,如1001、101等
    for (int i = 0; i < 4; i++) //分别处理千位、百位、十位、个位
    {
        if (!stoi(x.substr(cnt))) break;  //如果x当前位置及以后都为0,则直接退出,如1000等
        if (4 - i > x.size())    continue;  //排除x不满足4位数的情况,如111没有千位
        //如果x当前位置为0,分情况讨论
        if (x[cnt] == '0') {
            if (!flag)   ans += "ling ";  //如果之前没有输出过0,则输出0
            flag = 1; //置为1,防止重复输出,如1001中的0只能输出一次
            cnt++;
            continue;
        }
        ans += nums1[x[cnt++] - '0'] + " " + nums2[i];
    }
}
int main()
{
    string str;
    cin >> str;
    //先去掉负号的情况
    if (str[0] == '-') {
        ans += "Fu ";
        str = str.substr(1);
    }
    int n = str.size();
    int flag = 0; //用于判断是否为0的情况
    //处理第9位
    if (n == 9 && stoi(str.substr(0, 1))) {
        flag = 1;
        int a = stoi(str.substr(0, 1));
        str = str.substr(1);
        ans += nums1[a] + " Yi ";
    }
    //处理第5~8位
    if (n >= 5 && stoi(str.substr(0, str.size() - 4)))
    {
        flag = 1;
        work(str.substr(0, str.size() - 4));
        str = str.substr(str.size() - 4);
        ans += "Wan ";
    }
    //处理1~4位
    if (n > 0 && stoi(str))   flag = 1, work(str);
    if (!flag) ans += "ling"; //如果flag没变,则说明str为0
    //要去除末尾空格,否则官网会报错
    if (ans[ans.size() - 1] == ' ')  ans = ans.substr(0, ans.size() - 1);
    cout << ans;
    return 0;
}


目录
相关文章
|
存储 编译器 C语言
【C++】内联函数与快速读入read函数(整型)
【C++】内联函数与快速读入read函数(整型)
52 0
|
存储 C++ iOS开发
C++ 采用read()和write()读写二进制文件
以文本形式读写文件和以二进制形式读写文件的区别,并掌握了用重载的 >> 和 << 运算符实现以文本形式读写文件。在此基础上,本节继续讲解如何以二进制形式读写文件。 举个例子,现在要做一个学籍管理程序,其中一个重要的工作就是记录学生的学号、姓名、年龄等信息。这意味着,我们需要用一个类来表示学生,如下所示: class CStudent { char szName[20]; //假设学生姓名不超过19个字符,以 '\0' 结尾 char szId[l0]; //假设学号为9位,以 '\0' 结尾 int age; //年龄
112 0
|
C++
【PAT甲级 - C++题解】1040 Longest Symmetric String
【PAT甲级 - C++题解】1040 Longest Symmetric String
59 0
|
算法 C++
【PAT甲级 - C++题解】1044 Shopping in Mars
【PAT甲级 - C++题解】1044 Shopping in Mars
76 0
|
C++
【PAT甲级 - C++题解】1117 Eddington Number
【PAT甲级 - C++题解】1117 Eddington Number
70 0
|
存储 C++ 容器
【PAT甲级 - C++题解】1057 Stack
【PAT甲级 - C++题解】1057 Stack
68 0
|
存储 C++
【PAT甲级 - C++题解】1055 The World‘s Richest
【PAT甲级 - C++题解】1055 The World‘s Richest
74 0
|
10天前
|
编译器 C++
C++ 类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
56 30
|
24天前
|
存储 编译器 C++
C ++初阶:类和对象(中)
C ++初阶:类和对象(中)
|
1月前
|
存储 安全 编译器
【C++】类和对象(下)
【C++】类和对象(下)
【C++】类和对象(下)