• 【PAT甲级】1082 Read Number in Chinese


    ✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
    📚专栏地址:PAT题解集合
    📝原题地址:题目详情 - 1082 Read Number in Chinese (pintia.cn)
    🔑中文翻译:中文读数字
    📣专栏定位:为想考甲级PAT的小伙伴整理常考算法题解,祝大家都能取得满分!
    ❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

    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
    
    • 1

    思路

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

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

    1. 先处理负号情况,如果有负号就加入 ans 当中。
    2. 处理数字存在第 9 位的情况。注意,需要先判断第 9 位是否为 0 ,如果为 0 直接跳过不去处理,后面的 5~8 位和 1~4 位同理,例如 100000000 就不需要处理后面 8 位。
    3. 处理数字存在第 5~8 以及 1~4 的情况,处理函数如下:
      1. 先处理前缀 0
      2. 再分别处理千位、百位、十位和个位,因为数字位数不定,所以我们需要额外进行判断。
    4. 判断 flag 是否为 0 ,如果为 0 说明并没有经过步骤 23 的处理,它本身就为 0 ,直接加入 ans 即可。
    5. 如果 ans 最后有空格的话需要去除,否则官网会报格式错误,然后输出结果 ans 即可。

    代码

    #include
    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;
    }
    
    • 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
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
  • 相关阅读:
    外包干了2个月,技术退步明显了...
    C++继承和派生
    辽东楤木的高质量参考基因组组装和遗传转化体系开发
    对加密世界的经济误解:现金是储蓄?稀缺性创造价值?
    Android Studio的安装
    FFMPEG centos 安装指南
    程序员的护城河是什么?开源和免费就是卷死自己和同行
    OPENCV3.4.6+ RTX2060+VS2017编译记录
    分享Keil5设置忽略编译过程中的警告
    通俗易懂分析:Vite和Webpack的区别
  • 原文地址:https://blog.csdn.net/Newin2020/article/details/126514511