PAT_甲级_1082 Read Number in Chinese (25point(s)) (C++)【字符串处理/找规律】

目录

1,题目描述

题目大意

2,思路

算法

3,AC代码

4,解题过程

第一搏

第二搏


1,题目描述

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

题目大意

将数字按照汉语表达的方式输出。(是个狠题(╯‵□′)╯︵┻━┻,可能有同学连如何用汉语表达都不清楚,更不用说代码求解了,比如说我。。。)

 

2,思路

参考这位大神的思路@小·幸·运【PAT甲级A1082 Read Number in Chinese (25 分)】

找规律,没办法,看天赋╮(╯▽╰)╭ 

算法

  1. 将数字按照4位一节的方式,划分为若干节(若输入为0,特殊处理,直接输出即可);
  2. 判断正负,若为负,输出符号并截取数字部分:
  3. 按照规则,先输出高位再输出低位。用left和right分别指向每一节的首尾;
  4. 声明bool变量flag和isPrint判断判断是否有连续的0以及这一节的单位是否需要输出 (比如万)。当left所指的数字为0时,将flag置为true,不做输出;当left所指数字不为0flag==true时,说明该数字之前可能有若干个0,但只需要输出1次即可,然后输出该数字的中文表示以及单位,当这一节结束时,需要判断是否输出这一节的单位以及这一节的单位是多少,比如8000 0008 ba Qian Wan ling ba,8 0000 0008 ba Yi ling ba;

 

3,AC代码

 参考这位大神的代码@小·幸·运【PAT甲级A1082 Read Number in Chinese (25 分)】

#include<bits/stdc++.h>
using namespace std;

int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
    string unit[8] = {"Shi", "Bai", "Qian", "Wan", "Yi"};
    string digit[10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
    string s;
    cin>>s;
    if(s.size() == 1 && s[0] == '0'){           //输入为0时单独处理
        printf("ling");
        return 0;
    }
    if(s[0] == '-'){
        printf("Fu ");
        s = s.substr(1);
    }
    int left = 0, right = s.size() - 1;
    while(left + 4 <= right)                    //每四位划分一个区间 先输出高位 故先处理最左边的区间
        right -= 4;
    while(left < s.size()){
        bool flag = false;                      //判断是否有连续的0
        bool isPrint = false;                   //判断这一节的单位是否需要输出 比如万
        while(left <= right){                   //每次处理一节
            if(s[left] == '0'){
                flag = true;                    //此位是0 先做标记 不输出
            }else{
                if(flag)printf(" ling");        //在此节内 遇到不为0的数字
                flag = false;
                isPrint = true;                 //这一节的单位需要输出
                if(left > 0) printf(" ");       //除首个元素外 其余元素输出都是 '空格 元素'的形式
                printf("%s", digit[s[left] - '0'].c_str());
                if(left != right)               //left等于right时 即个位 不需要输出
                    printf(" %s", unit[right - left - 1].c_str());
            }
            left++;
        }
        if(isPrint && right != s.size() - 1)    //本节中有输出 且不为最后一节(若只剩4位数 不需要输出节的单位)
            printf(" %s", unit[(s.size() - 1 - right) / 4 + 2].c_str());
        right += 4;
    }
    return 0;
}

 

4,解题过程

第一搏

简直是魔鬼。

但是能得一分是一分,没有考虑复杂的情形,按照最简单的来了

#include<bits/stdc++.h>
using namespace std;

int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
    string unit[8] = {"Shi", "Bai", "Qian", "Wan", "Yi"};
    string num[10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
    vector<int> data;
    string s;
    bool sign;//标志 万 是否输出
    cin>>s;
    if(s[0] == '-'){
        printf("Fu");
        s = s.substr(1);
    }
    for(int i = s.size() - 1; i >= 0; i--){
        data.push_back(s[i] - '0');
    }
    int maxSize = data.size();
    if(data.size() >= 5) sign = true;
    for(int i = data.size() - 1; i >= 0; i--){
        if(data[i] == 0){
            if(data[i + 1] != 0) printf(" ling");
        }else{
            if(i == 8) printf(" %s Yi", num[data[i]].c_str());
            else if(i == 7 || i == 3) printf(" %s Qian", num[data[i]].c_str());
            else if(i == 6 || i == 2) printf(" %s Bai", num[data[i]].c_str());
            else if(i == 5 || i == 1) printf(" %s Shi", num[data[i]].c_str());
            else if(i == 4) {
                printf(" %s", num[data[i]].c_str());
                if(sign) printf(" Wan");
            }
            else if(i == 0) printf(" %s", num[data[i]].c_str());

        }
    }
    return 0;
}

一半的分数。。。也还行

第二搏

召唤大神!@小·幸·运【PAT甲级A1082 Read Number in Chinese (25 分)】(这是我找到的逻辑比较清晰,而且代码量少的的代码,先膜为敬!)

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值