模拟题 —— 字符串拔高题1(PAT 甲级 1082 Read Number in Chinese (25分) )

目录概要

一 模拟题介绍

二 题目描述

三 题意简介

四 题解思路
4.1 题解说明
4.2 题解初思路
4.3 解题讨论的情况
4.4 解题总结
4.5 解题心得

五 题解C++ 代码

六 官方题解(算法笔记)

一 ,模拟题介绍

入门模拟题 分为简单模拟,查找元素,图形输出,日期处理,进制转换字符串处理等等!

何为模拟题?

模拟题是一类“题目怎么说,你就怎么做的”的一类题目。此类题目不涉及算法,完全根据题目描述进行代码的编写,主要考察代码能力!!!

模拟题 ———— 字符串处理(拔高题)
【PAT 甲级 1082】 Read Number in Chinese (25分)

字符串处理问题很能体现代码能力的一种题型,一般实现逻辑会非常麻烦,而且可能
会有很多的细节和边界情况,因此对代码能力弱的会有较大难度,但这也是进阶大神
的必经之路。

唯一的方法:多做多想积累经验!!!

二 ,题目描述

PAT 甲级 1082 Read Number in Chinese (25分)

Given an integer with no more than 9 digits, you are supposed toread it in the
traditional Chinese way. Output Fu first if it is negative. For example, -12345
6789 is read as Fu yi Yi er Qian san Bai si Shiwu 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

Input Specification:

Each input file contains one test case, which gives an  integer with no more than 9 digits.

Output Specification:

For each test case, print in a line the Chinese way of reading the number. The 
characters are separated by a space and there must be no extra space at the 
end of the line.

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

三 ,题意简介

输入一个不超过9位的整数(即在int范围内),按照要求输出我们中国的读整数的方式,如果该整数是负数首选输出“Fu”,如果数字中间有0需输出ling。
-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.1 题解说明

题目描述的题意很简单,可是否真的如此呢?
中间的复杂度可能会使你望而却步,但是不要紧,干就完事啦!

该题大概花费我3个小时左右时间,大概从中午14点到17点左右吧!差不多整整一下午.该题考虑的细节很多,也是锻炼思维严谨的一道好题!!!
(前提是自己认认真真做的,切记不要一上手即百度,)

4.2 题解初思路

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

首先我们来考虑第一个例子 (先去掉负号)
数字字符串从左往右,文字字符串也是从左往右完全符合生活习惯

可能有小伙伴问?从左往右如何知道最高位是哪个?

我们来设置两个数组
char num[10][5] = {“ling”, “yi”, “er”, “san”, “si”, “wu”, “liu”, “qi”, “ba”, “jiu”};
char unit[10][5] = {"" ,"",“Shi”, “Bai”, “Qian”, “Wan”,“Shi”, “Bai”, “Qian”,“Yi”};
char s[12] = {‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’ };

最高位9位,使单位与unit的小标一一对应,具体实现看部分思路代码

int len = strlen(s);
for (int i = 0; i <= strlen(s) - 1; i++)
{
  if (i != strlen(s) - 1)
      printf("%s %s", num[s[i] - '0'], unit[len - i]);
  else {
         printf("%s", num[s[i] - '0']);
  }

这样我们可以完全打印第一个样例,也说明设置该两个数组的作用以及方便之处(尤其是unit数组)

4.3 解题讨论的情况

当然既然我拿出来这道题目,肯定不会如此之简单!!!

我们来看几个例子(这里只讨论正整数的各种情况,负整数一样即外加一个Fu,再改变遍历下标的起始位置,无需过多讨论)

102000783
yi Yi ling er Bai Wan ling qi Bai ba Shi san

100000007
yi Yi ling qi

100000600
yi Yi ling liu Bai

100024008
yi Yi ling er Wan si Qian ling ba

103040760
yi Yi ling san Bai ling si Wan ling qi Bai liu Shi
  1. 末尾如果全部是0,比如100007000,只会打印qi Bai末尾不能有多余空格

  2. 如果0在中间即100000600,这里是不会打印Wan的

  3. 什么情况下又会打印Wan呢?且又打印0呢? 比如102000783

  4. 连续的 0 又如何处理?

  5. 是否需要打印空格,什么情况下打印空格?等等之类的各种细节

  6. 你考虑到这些问题啦吗?

我们先来看正整数是如何解决的,代码部分我会更加详细的注释

#include <cstdio>
#include <cstring>

char num[10][5] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
char unit[10][5] = {"" ,"","Shi", "Bai", "Qian", "","Shi", "Bai", "Qian","Yi"};//这里我把“Wan”去掉啦,因为不一定会打印Wan,刚才的例子可以证明

char s[12];
//我这里先考虑正整数的情况(包括0)
int main()
{
    scanf("%s", &s);
    //---------------------------------------------
      int k = strlen(s) - 1;//
      for (int i = strlen(s) - 1; i >= 0; i--)
           if (s[i] != '0'){
               k = i;
               break;
           }
    //k表示处理掉情况1 ,末尾有连续 0
    //------------------------------------------------
       int len = strlen(s);//表示长度
       bool falg = false;//来判断是否会打印Wan
    //--------------------------------------

	//------------------------------------------------------------------
       if (len == 9)  { //表示9位,最高位为亿
           if (s[1] != '0' || s[2] != '0' || s[3] != '0' || s[4] != '0')
               falg = true;//如果在千万,百万,十万以及个万位不为0,说明是需要打印Wan的
           for (int i = 0; i <= k; i++)//从0开始遍历到k
           {
               if (s[i] == '0' && s[i + 1] != '0')//连续0的处理情况
               {
                   if (i != 4)//假如个位万位为0,千位不为为0,那么是不需要打ling的,举例104003007
                       printf("ling ");
               }
               if (s[i] != '0')
               {
                   if(i == k && k < len - 1)//如果k不在最后一个位置,我们是需要打印它的单位的,举例10400300,最后打印 san Qian
                       printf("%s %s", num[s[i] - '0'], unit[len - i]);
                   else if ((i == k && k == len - 1) || i == 4)
                   {//如果k在最后一个位置,我们是不需要打印它的单位的,举例104000003,最后打印san
                       printf("%s", num[s[i] - '0']);
                       if (i == 4)//当然这里还需考虑个位万位置不为0的情况,那么我们需要加空格的,比如104033007
                           printf(" ");
                   }
                   else//正常情况下正常打印即可
                       printf("%s %s ", num[s[i] - '0'], unit[len - i]);
               }
               if (i == 4 && falg)//Wan打印的情况
                   printf("Wan ");
           }
       }

       //---------------------------------------------------------------
       else if (len >= 5)//这里表示长度大于或等于万位 但小于 亿位
       {//代码部分基本一致,主要是Wan打印的处理不同而已
           for (int i = 0; i < (len - 4); i++)
           {
               if (s[i] != '0') {
                   falg = true;
                   break;
               }
           }
           for (int i = 0; i <= k; i++)
           {
               if (s[i] == '0' && s[i + 1] != '0')
               {
                   if (i != len - 5)
                       printf("ling ");
               }
               if (s[i] != '0')
               {
                   if(i == k && k < len - 1)
                       printf("%s %s", num[s[i] - '0'], unit[len - i]);
                   else if ((i == k && k == len - 1) || i == len - 5)
                   {
                       printf("%s", num[s[i] - '0']);
                       if (i == len - 5)
                           printf(" ");
                   }
                   else
                       printf("%s %s ", num[s[i] - '0'], unit[len - i]);
               }
               if (i == len - 5 && falg)
                   printf("Wan ");
           }
       }
//-------------------------------------------------------------

       else {//长度小于或等于千位的情况
//千位情况不用考虑Wan,只需考虑连续0 以及k的位置
           for (int i = 0; i <= k; i++)
           {
               if (s[i] == '0' && s[i + 1] != '0')
               {
                   if (k == 0)
                       printf("ling");//如果正整数位0,那么末尾是不需要空格的,处理0的情况
                   else printf("ling ");

               }
               if (s[i] != '0')
               {
                   if(i == k && k < len - 1)
                       printf("%s %s", num[s[i] - '0'], unit[len - i]);
                   else if (i == k && k == len - 1)
                   {
                       printf("%s", num[s[i] - '0']);
                   }
                   else
                       printf("%s %s ", num[s[i] - '0'], unit[len - i]);
              }
           }
        }
  return 0;
 }
4.4 解题总结

正整数的情况(包括0) 讨论完毕!
负整数和正整数的情况基本一样,开头需要打印"Fu“,位置从1开始遍历,其他的部分需要修改一下,这都不是事!具体看代码

4.5 解题心得

其实我并不是一开始既能做出来的。我一开始是望而却步的,我没有任何思路的,我感觉超级难。但是克服恐惧的唯一办法是面对它!

我的解题思路差不多如上所述。一开始只是实现例1的基本输入输出。后来0之间的判断我手足无措。但我没有放弃,我短暂的离开电脑休息一会,我在想有哪些情况需要判断,连续的0如何判断,Wan何时不打印何时打印?慢慢的多种情况浮现在我的脑海里。我打开电脑继续写代码,发现我想的情况基本实现。开心呀! 接着测试其他的情况,慢慢的优化代码才有啦 ,处理个位万的代码,处理k不在末尾的情况,处理空格的情况等等。后面我提交的时显示部分正确,可能还有情况没考虑到,比如-1,再比如0等等,进一步修改,果然最后全部正确!

做题中的思考就是我们的进步,本次解题使我的思维更加严谨!!!

五 ,题解C++ 代码

代码已Accept!!!

未加载请刷新

#include <cstdio>
#include <cstring>

char num[10][5] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
char unit[10][5] = {"" ,"","Shi", "Bai", "Qian", "","Shi", "Bai", "Qian","Yi"};
char s[12];

//本题考查的主要问题在0的处理
int main()
{
     scanf("%s", &s);
   //分两种情况讨论
    if (s[0] == '-')
    {//负数的情况要从1开始的,后面相应的位置要更该,总之要小心喲
        printf("Fu ");
        
        int k = strlen(s) - 1;
        for (int i = strlen(s) - 1; i >= 1; i--)
            if (s[i] != '0'){
                k = i;
                break;
            }
        int len = strlen(s) - 1;//注意长度要减1,减去负号
        bool falg = false;
        //--------------------------------------

        if (len == 9) {
            if (s[2] != '0' || s[3] != '0' || s[4] != '0' || s[5] != '0')
                falg = true;
            for (int i = 1; i <= k; i++)//从1开始
            {
                if (s[i] == '0' && s[i + 1] != '0')
                {
                    if (i != 5)
                        printf("ling ");
                }
                if (s[i] != '0')
                {
                    if(i == k && k < strlen(s) - 1)
                        printf("%s %s", num[s[i] - '0'], unit[len - i + 1]);
                    else if ((i == k && k == strlen(s) - 1) || i == 5)
                    {
                        printf("%s", num[s[i] - '0']);
                        if (i == 5)
                            printf(" ");
                    }
                    else
                        printf("%s %s ", num[s[i] - '0'], unit[len - i + 1]);
                }
                if (i == 5 && falg)
                    printf("Wan ");
            }
        }

     //--------------------------------------------------------------
        
        else if (len >= 5)
        {
            for (int i = 1; i < (len - 3); i++)
            {
                if (s[i] != '0') {
                    falg = true;
                    break;
                }
            }
            for (int i = 1; i <= k; i++)
            {
                if (s[i] == '0' && s[i + 1] != '0')
                {
                    if (i != len - 4)
                        printf("ling ");
                }
                if (s[i] != '0')
                {
                    if(i == k && k < strlen(s) - 1)
                        printf("%s %s", num[s[i] - '0'], unit[len - i + 1]);
                    else if ((i == k && k == strlen(s) - 1) || i == len - 4)
                    {
                        printf("%s", num[s[i] - '0']);
                        if (i == len - 4)
                            printf(" ");
                    }
                    else
                        printf("%s %s ", num[s[i] - '0'], unit[len - i + 1]);
                }
                if (i == len - 4 && falg)
                    printf("Wan ");
            }
        }
//------------------------------------------------------
        else {

            for (int i = 1; i <= k; i++)
            {
                if (s[i] == '0' && s[i + 1] != '0')
                {
                    printf("ling ");
                }
                if (s[i] != '0')
                {
                    if(i == k && k < strlen(s) - 1)
                        printf("%s %s", num[s[i] - '0'], unit[len - i + 1]);
                    else if (i == k && k == strlen(s) - 1)
                    {
                        printf("%s", num[s[i] - '0']);
                    }
                    else
                        printf("%s %s ", num[s[i] - '0'], unit[len - i + 1]);
               }
            }
         }
    }
//------------------------------------------------------
//------------------------------------------------------
//------------------------------------------------------
    else//正数
    {
        //---------------------------------------
        int k = strlen(s) - 1;
        for (int i = strlen(s) - 1; i >= 0; i--)
            if (s[i] != '0'){
                k = i;
                break;
            }
        int len = strlen(s);
        bool falg = false;
        //--------------------------------------


        if (len == 9) {
            if (s[1] != '0' || s[2] != '0' || s[3] != '0' || s[4] != '0')
                falg = true;
            for (int i = 0; i <= k; i++)
            {
                if (s[i] == '0' && s[i + 1] != '0')
                {
                    if (i != 4)
                        printf("ling ");
                }
                if (s[i] != '0')
                {
                    if(i == k && k < len - 1)
                        printf("%s %s", num[s[i] - '0'], unit[len - i]);
                    else if ((i == k && k == len - 1) || i == 4)
                    {
                        printf("%s", num[s[i] - '0']);
                        if (i == 4)
                            printf(" ");
                    }
                    else
                        printf("%s %s ", num[s[i] - '0'], unit[len - i]);
                }
                if (i == 4 && falg)
                    printf("Wan ");
            }
        }

        //---------------------------------------------------------------------
        else if (len >= 5)
        {
            for (int i = 0; i < (len - 4); i++)
            {
                if (s[i] != '0') {
                    falg = true;
                    break;
                }
            }

            for (int i = 0; i <= k; i++)
            {
                if (s[i] == '0' && s[i + 1] != '0')
                {
                    if (i != len - 5)
                        printf("ling ");
                }
                if (s[i] != '0')
                {
                    if(i == k && k < len - 1)
                        printf("%s %s", num[s[i] - '0'], unit[len - i]);
                    else if ((i == k && k == len - 1) || i == len - 5)
                    {
                        printf("%s", num[s[i] - '0']);
                        if (i == len - 5)
                            printf(" ");
                    }
                    else
                        printf("%s %s ", num[s[i] - '0'], unit[len - i]);
                }
                if (i == len - 5 && falg)
                    printf("Wan ");
            }
        }
//------------------------------------------------------
        else {

            for (int i = 0; i <= k; i++)
            {
                if (s[i] == '0' && s[i + 1] != '0')
                {
                    if (k == 0)
                        printf("ling");
                    else printf("ling ");

                }
                if (s[i] != '0')
                {
                    if(i == k && k < len - 1)
                        printf("%s %s", num[s[i] - '0'], unit[len - i]);
                    else if (i == k && k == len - 1)
                    {
                        printf("%s", num[s[i] - '0']);
                    }
                    else
                        printf("%s %s ", num[s[i] - '0'], unit[len - i]);
               }
            }
         }
    }
    return 0;
}

六,官方题解(算法笔记)

由于本人当时提交代码过于冗长!这里给出官方题解

其实我的代码不是重点,重点是解题思路

官方题解代码比较好理解,这里不做过多的注释与说明
(其实看完我写的题解,基本即可理解)

#include <cstdio>
#include <cstring>

char num[10][5] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
char wei[5][5] = {"Shi", "Bai", "Qian", "Wan", "Yi"};
int main()
{
    char str[15];
    gets(str);

    int len = strlen(str);
    int left = 0, right = len - 1;
    if (str[0] == '-') {
        printf("Fu");
        left++;
    }
    while (left + 4 <= right)
    {
        right -= 4;
    }
    while (left < len)
    {
        bool flag = false;
        bool isPrint = false;
        while (left <= right)
        {
            if (left > 0 && str[left] == 0)
                flag = true;
            else {
                if (flag == true) {
                    printf(" ling");
                    flag = false;
                    }
                if (left > 0) printf(" ");
                printf("%s", num[str[left] - '0']);
                isPrint = true;
                if (left != right) {
                    printf(" %s", wei[right - left - 1]);
                }
            }
            left++;
        }
        if (isPrint == true && right != len - 1)
            printf(" %s", wei[(len - 1 - right) / 4 + 2]);
        right += 4;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值