jyy56350895 发表于 2021-9-10 00:14

这道“币值转换”题把我直接难吐了,最优的思路应该是什么

网上的答案我看到的很多都是在凑检测点都是有缺陷的,这问题太复杂了,中华文化博大精深,这读个数背后的逻辑思维也太复杂了。题目:(来源PTA题目详情 (pintia.cn))
7-23 币值转换 (20分)输入一个整数(位数不超过9位)代表一个人民币值(单位为元),请转换成财务要求的大写中文格式。如23108元,转换后变成“贰万叁仟壹百零捌”元。为了简化输出,用小写英文字母a-j顺序代表大写数字0-9,用S、B、Q、W、Y分别代表拾、百、仟、万、亿。于是23108元应被转换输出为“cWdQbBai”元。【最后这里我感觉应该是写错了,应该接着还有“ai”表示“零八”】【其实就是转换成中文表示】输入格式:输入在一行中给出一个不超过9位的非负整数。输出格式:在一行中输出转换后的结果。注意“零”的用法必须符合中文习惯。输入样例1:813227345输出样例1:iYbQdBcScWhQdBeSf输入样例2:6900输出样例2:gQjB【我的思路】一、肯定是先把数拆开到数组。这个简单。这样a-a就代表着个位到亿位。        for(i=1;i<=9;i++){    //得到每一位
                x=pow(10,i);
                y=pow(10,i-1);
                r=rmb%x/y;
        }二、然后就复杂了:①最普通的情况——连续的非0数,只要把每一位都switch转换一下,再每一位switch加上单位就行了;比如123456789就是一亿两千三百四十五万六千七百八十九;②稍微复杂一点就是要判断一下始末,否则123400000,就变成一亿两千三百四十零万零千零百零十零了;还有这个万比较特殊,如果万前面的数是零,如就少个万字。③然后就是中间缺!!!!如果是103400000,就是一亿零三百四十万,缺了读零;如果是100000089,就是一亿零八十九,中间只读一次零;如果是120000089,就是一亿两千万零八十九,又多个万;【这个万也是个大麻烦】如果(如果不出来了,我脑子里已经混乱了,我也不知道还有没有别的情况了,今天晚上睡觉肯定全是一亿两千三百四十五万六千七百八十九)所以如果定义一个变量去数零,至少还要考虑万的情况。④还有一个情况,312,我们一般读三百一十二,12我们一般读十二,这个一怎么省。。。。(我脑子已经不转了)⑤应该没有其他情况了。我考虑过整体依次出结果,if套了无数层,乱了。我还考虑过把亿位(第1位)万位(第2-5位)个位(6-9位)分开出结果。因为亿位就一位很简单,万位其实就是个位加个万,然后三者中间有零只读一个零就行,但是每个都单独写,又得考虑更多奇葩情况,我已经破防了,想不明白了。请各位赐教!!

爱飞的猫 发表于 2021-9-10 07:42

本帖最后由 jixun66 于 2021-9-10 07:44 编辑

随手一搜:https://blog.csdn.net/yeternity/article/details/71595813

解析:
主要是何时输出0的问题

1、以10000为小节,小节的结尾即使是0,也不输出0(如101001,一十万一千零一,万位上的0不输出)
2、两个非0数字之间 要且只能 输出1个0(如1001,一千零一,十位和百位的0只输出一个0)
3、当小节的 ”千“ 位是0时,若本小节无其它数字,则不输出0,否则就要用0(如0100,一百,第一个0不输出;10100,一万零一百,第一个0输出)
4、只有一个0时,输出零

#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
int main () {
      int len, i = 0, flag = 0;
      string s;
      char unit = {'0','S', 'B', 'Q', 'W', 'S', 'B', 'Q', 'Y'};
      cin >> s;
      len = s.length();
      if( s == "0" ) {//只有0时,输出a (规则4)
                printf("a");
      }
      else {
                while( i < len ) {
                        //连续遇到0,直到第一次遇到不是0(规则2,3)且不是倒数第4位 (规则1)
                        if ( s != '0' && flag && i != len - 4 )
                              printf("a");
                        //连续遇到0,且是倒数第4位,则输出W。(比如100001,十万零一)
                        else if ( flag && i == len - 4 )
                              printf("W");
                        if ( s != '0' ) {//如果不是0
                              printf( "%c", s + 49 );
                              if ( unit != '0' ) //如果不是个位,输出权位
                                        printf( "%c", unit );
                              flag = 0;      //标记遇到不是0
                              i++;
                        }
                        else {      //碰到0,或者连续碰到0
                              i++;
                              flag = 1;      //标记遇到0
                        }
                }
      }
      return 0;
}

Spa495 发表于 2021-9-10 08:29

光看到这串代码我就要吐了,楼主是止吐剂啊

b0y 发表于 2021-9-10 09:28

可以参考小学4年级的关于数字分位的那节课

jyy56350895 发表于 2021-9-10 09:51

jixun66 发表于 2021-9-10 07:42
随手一搜:https://blog.csdn.net/yeternity/article/details/71595813




啊这,哥,其实我刚学c,还没学c++,我给忘了说了。

Prozacs 发表于 2021-9-10 10:32

num = input()
print(num)
len1 = len(num)
if num == '0':
    print('a')
    exit(0)
k = 0
for i in num[::-1]:
    if i != '0':
      break
    k += 1
k = len1 - k
for i in range(k):
    if num != '0':
      print(chr(ord('a') + int(num)), end='')
      if len1 - i - 1 == 1 or len1 - i - 1 == 5:
            print('S', end='')
            if len1 - i - 1 == 5 and num1] == '0' and i + 1 < len1:
                print('W', end='')
      elif len1 - i - 1 == 2 or len1 - i - 1 == 6:
            print('B', end='')
            if len1 - i - 1 == 6 and num1] == '0' and i + 1 < len1:
                print('W', end='')
      elif len1 - i - 1 == 3 or len1 - i - 1 == 7:
            print('Q',end='')
            if len1 - i - 1 == 7 and num1] =='0' and i+1<len1:
                print('W',end='')
      elif len1 - i - 1 == 4:
            print('W',end='')
      elif len1 - i - 1 == 8:
            print('Y',end='')
    else:
      if num1] != '0':
            print('a',end='')

不知道这样解对不对。你提的第四点我没有加。毕竟12也有读壹拾贰的

wjx18701147817 发表于 2021-9-10 11:19

关于读0问题,我觉得可以看下小学数学书里面是咋样说的,剩下的应该都是转换问题

再见babay 发表于 2021-9-10 12:55

浅嵌套,这应该不会看吐吧{:17_1062:}
public String convert(int originalNum) {
      String targetStr = ""; // 要返回的结果
      
      //String[] numChar = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
      String[] numChar = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
      
      //String[] unitChar = {"", "S", "B", "Q"};
      String[] unitChar = {"", "十", "百", "千"};
      
      //String[] groupUnitChar = {"", "W", "y"};
      String[] groupUnitChar = {"", "万", "亿"};


      int tmp = originalNum;
      int nums[] = new int;
      
      // 默认输入9位数,提取每位上的数字
      for (int i = 0; i < nums.length; i++) {
            nums = tmp % 10;
            tmp = tmp / 10;
      }

      int zeroCount = 0;
      
      // 从高位开始,转换每位上的数字
      for (int i = nums.length - 1; i >= 0; i--) {
            String tmpStr = "";
            
            boolean fillZero = false;
                        
            int numIndex = nums;
            int unitIndex = i % 4;
            if (nums > 0) {   //该位非零,拼接
                tmpStr = tmpStr + numChar + unitChar;
                fillZero = true;
               
            } else if(!targetStr.equals("")) { // 检测是否为有效的零,有效是指该位之前出现过非零数字
                zeroCount++;
               
            } else {
                continue;
               
            }
            
            if (i % 4 == 0) {
                tmpStr += groupUnitChar;
            }            
            
            if (zeroCount > 0 && fillZero) {
                tmpStr = numChar + tmpStr;
                zeroCount = 0;
            }
            
            targetStr += tmpStr;
      }
      return targetStr;
    }

hearne 发表于 2021-9-10 13:13

就是纯枚举,考虑所有情况,多写几个if,把各种情况在纸上写好先

globlefaster 发表于 2021-9-10 13:30

还有一种情况,
123456789就是一亿两千三百四十五万六千七百八十九
10200就是一万零二百
页: [1] 2
查看完整版本: 这道“币值转换”题把我直接难吐了,最优的思路应该是什么