首页 > 试题广场 >

Read Number in Chinese (25)

[编程题]Read Number in Chinese (25)
  • 热度指数:7724 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
Given an integer with no more than 9 digits, you are supposed to read it in the traditional Chinese way. Output "Fu" first if it is negative. For example, -123456789 is read as "Fu yi Yi er Qian san Bai si Shi wu 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".

输入描述:
Each input file contains one test case, which gives an integer with no more than 9 digits.


输出描述:
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.
示例1

输入

-123456789

输出

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

突然记起小学数学老师教念读数的场景。。。


分级

四位一级(xxxx)|亿|(yyyy)|万|(zzzz)

  1. 每级内部的命名规则都一样 (例如:几千几百几十几)
  2. 级间使用级单位分割(例如:几亿几万)

我的策略是:使用大小为3的int数组,存储每个部分的数字。再循环读出每级内部的数字。

零的问题

出现零的情况为:

  1. 两个非零数字之间有一或多个零出现只念一个(例如:X00X几千零几 X0X0几千零几十 0X0X_几百零几十)
  2. 除去每级的最低位的零
    例如:
    X0X000 几十万几千,而不是几十万零几千 X0X0000000 几十亿几百万,而不是几十亿零几百万

我的策略是:出现零时 并且 零前有非数字时,记录至布尔型变量noZero。在出现第二个非零数字时,输出零。

格式问题

空格问题:简单粗暴并且非常减少思考量地使用一个变量记录输出单词的个数。当变量为0时,不输出空格。不为0时,在每个单词前面输出空格。

代码

#define MY_DEBUG 0
#include <stdio.h>
int J[] = {
    1, 10, 100, 1000,
    10000, 100000, 1000000, 10000000,
    100000000};
const char cNum[10][5] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
const char cUnit[10][9] = {"Ge", "Shi", "Bai", "Qian"};
const char cDivi[2][4] = {"Yi", "Wan"};
int main(int argc, const char *argv[])
{
    int number;
    scanf("%d", &number);
    if(number == 0){
        printf("ling\n");
        return 0;
    }
    if(number < 0){
        printf("Fu ");
        number = -number;
    }
    //四位一级 (xxxx)|Yi|(yyyy)|Wan|(zzzz)
    //每级结束后输出级单位(Yi、Wan)
    int unit[3];
    unit[0] = number/J[8];
    unit[1] = (number%J[8])/J[4];
    unit[2] = (number%J[4])/J[0];
    //使用noZero标记 是否在非零数字间出现合适的零
    bool noZero = true;
    //使用printCnt维护首单词前无空格,之后输入的单词都在前面加一个空格
    int printCnt = 0;
    //遍历每级
    for (int i = 0 ; i < 3 ; i++) {
#if MY_DEBUG == 1
        printf("Unit :%4d ->", unit[i]);
#endif
        int temp = unit[i];
        //每级内部的命名规则都一样 几千几百几十几
        for (int j = 3 ; j >= 0 ; j--) {
            //当前位置分布
            //
            //       | x x x x | y y y y | z z z z |
            // i    =  0         1         2
            // j    =  3 2 1 0 | 3 2 1 0 | 3 2 1 0
            //curPos=  b a 9 8   7 6 5 4   3 2 1 0
            //
            //curPos = (2-i)*4+j
            int curPos = 8-i*4+j;
            //最多9位数。
            if(curPos >= 9) continue;
            int cur = (temp/J[j]) % 10;
#if MY_DEBUG == 1
            printf(" %d", cur);
#endif
            if(cur != 0){
                if(!noZero){
                    printf(printCnt++ == 0?"ling":" ling");
                    noZero = true;
                }
                if(j == 0)
                    printf(printCnt++ == 0?"%s":" %s", cNum[cur]);
                else
                    printf(printCnt++ == 0?"%s %s":" %s %s", cNum[cur], cUnit[j]);
            }else{
#if MY_DEBUG == 1
                printf("_%d ", J[curPos]);
#endif
                // 100020
                // ____^_ --> curPos = 1
                // number / 10 >= 10 表示 curPos 前有非零数字
                // j != 0            表示 0 出现的位置不为每级的最后一位
                if(noZero && j != 0 && number/J[curPos]>=10){
                    noZero = false;
                }
            }
        }
        if(i != 2 && unit[i] > 0){
            printf(" %s", cDivi[i]);
        }
#if MY_DEBUG == 1
        printf("\n");
#endif
    }
    return 0;
}
编辑于 2018-04-07 18:47:07 回复(0)
#include <iostream>
#include <cstring>
using namespace std;
int main(){
    int len,k=0,num=0;
    char a[15],s[30][5],c[10][5]={"Shi","Bai","Qian","Wan","Yi"};
    char b[15][5]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
    cin>>a;len=strlen(a);
    if(a[0]=='-'){                                                                 //先输出负数符号
        cout<<"Fu ";
        k++;
    }
    if(len==1&&a[0]=='0') cout<<b[0];                                              //特例,只有一位数且为0时,直接输出"ling"
    bool flag=false;
    for(int i=k;i<len;i++){
        if(a[i]=='0'&&len-i-1!=4) flag=true;                                       //当前位为0且不是个位,低一位不为0且不为千位(千位的高一位为0时不用读零,如808000),输出“ling”                                                                           
        if(a[i]!='0'){                   
            if(flag==true){                                                       //没有i+1<len 这个条件的话输入10会输出"yi Shi ling"
                strcpy(s[num++],b[0]);
                flag=false;
            }
            strcpy(s[num++],b[a[i]-'0']);                                          //当前位不为0时
            if((len-i)%4==2) strcpy(s[num++],c[0]);                                //十,输出"Shi"
            if((len-i)%4==3) strcpy(s[num++],c[1]);                                //百,输出"Bai"
            if((len-i)%4==0) strcpy(s[num++],c[2]);                                //千,输出"Qian"
        }
        if(len-i==5){
            if(a[i]=='0'&&a[i-1]=='0'&&a[i-2]=='0'&&a[i-3]=='0');                  //万,输出"Wan"(没有出现万这个小节位数全为0时,如800000008)
            else strcpy(s[num++],c[3]);
        }
        if(len-i==9) strcpy(s[num++],c[4]);                                        //亿,输出"Yi"
    }
    for(int i=0;i<num;i++){
        cout<<s[i];
        if(i!=num-1)
            cout<<" ";
    }
    return 0;
}

发表于 2018-01-17 20:31:14 回复(1)
#include<iostream>
#include<vector>
#include<string>

using namespace std;

vector<string> num_c{"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
vector<string> delim{"Yi", "Wan"};
vector<string> table{"Qian", "Bai", "Shi"};
void output(int num, bool& flag)
{
	vector<int> vec;
	while(num != 0){
		vec.push_back(num % 10);
		num /= 10;
	}
	if(flag && vec.size() < 4){
		cout <<"ling ";
	}
	flag=true;
	int end;
	for(end = 0; end < vec.size()&&vec[end]==0; ++end);
	for(int i = vec.size()-1; i >= end; --i){
		if(vec[i] == 0){
			cout << "ling ";
			while(vec[i] == 0) --i;
			if(i < end)
				break;
		} 
		cout << num_c[vec[i]];
		if(vec[i] != 0 && i!= 0) cout << " "<<table[3-i];
		if(i!=end) cout<<" ";
	}
}
int main()
{
	int n;
	cin >> n;
	if(n < 0){
		cout << "Fu ";
		n = -n;
	}
	if(n == 0) cout << "ling";
	vector<int> pair_n;
	while(n != 0){
		pair_n.push_back(n%10000);
		n /= 10000;
	}
	bool flag = false;
	for(int i = pair_n.size()-1; i >= 0; --i){		
		if(pair_n[i] == 0){
			while(pair_n[i] == 0) --i;
			if(i == -1) break;
		}
		output(pair_n[i], flag);
		if(i != 0) cout <<" "<< delim[2-i]<<" ";
	}
}

测试用例:
-90000

对应输出应该为:

Fu jiu Wan

你的输出为:

Fu jiu Wan ling san Shi san  
  这个错误是怎么回事?
发表于 2021-03-06 20:50:42 回复(0)
package com.jingmin.advanced;

import java.util.Scanner;

/**
 * @author : wangjm
 * @date : 2020/1/17 01:33
 * @discription : https://www.nowcoder.com/pat/1/problem/4312
 */
public class Advanced1002 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        System.out.println(new ChineseNumber(n));
        scanner.close();
    }

}

class ChineseNumber {
    /**
     * 对应的值
     */
    private int value;

    /**
     * 对应的中文
     */
    private String chinese;

    /**
     * 非0标志
     */
    boolean nonZero = false;

    /**
     * 上一位为0,标志
     */
    boolean lastBitZero = false;

    /**
     * 中文拼音 0-9
     */
    private static String[] CHINESE_NUM = new String[]{"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};

    /**
     * 十进制位基:千,百,十,个
     */
    private static String[] CHINESE_BASE = new String[]{" Qian ", " Bai ", " Shi ", " "};

    public ChineseNumber(int value) {
        this.value = value;
        produceChinese();
    }

    private void produceChinese() {
        StringBuilder sb = new StringBuilder();
        int n = this.value;
        //判断正负
        if (n < 0) {
            sb.append("Fu ");
            n = -n;
        } else if (n == 0) {
            this.chinese = "ling";
            return;
        }

        int bufferLength = sb.length();
        //获取亿级以上部分(int 最大20+亿)
        int[] bits = new int[]{0, 0, n / 1000000000, n / 100000000 % 10};
        //输出中文到StringBuilder中
        print4Bit(sb, bits);
        //亿级以上不全为0
        if (bufferLength != sb.length()) {
            sb.append("Yi ");
            bufferLength = sb.length();
        }

        //获取万到千万部分
        bits = get4Bit(n % 100000000 / 10000);
        //输出中文到StringBuilder中
        print4Bit(sb, bits);
        //万到千万部分不全为0
        if (bufferLength != sb.length()) {
            sb.append("Wan ");
            bufferLength = sb.length();
        }

        //获取个位至千位
        bits = get4Bit(n % 10000);
        //输出中文到StringBuilder中
        print4Bit(sb, bits);
        //更新该实例的中文字段
        this.chinese = sb.toString().trim();
    }

    /**
     * 4位数按10进制位转存到数组
     */
    private static int[] get4Bit(int num) {
        int ge = num % 10;
        int shi = num / 10 % 10;
        int bai = num / 100 % 10;
        int qian = num / 1000;
        return new int[]{qian, bai, shi, ge};
    }

    /**
     * 输出bits, 其0,1,2,3位分别是千,百,十,个位
     */
    private void print4Bit(StringBuilder sb, int[] bits) {
        int bufferLength = sb.length();
        //bits 0,1,2,3位分别是千,百,十,个位
        for (int i = 0; i < 4; i++) {
            if (bits[i] != 0) {
                //处理数字中间的0:当前位不为0,上一位为0,且前面有不为0的位
                if (lastBitZero && nonZero) {
                    sb.append(CHINESE_NUM[0]).append(" ");
                }
                //以"一十"打头的数字,只输出"十"
//                if (i == 2 && bits[i] == 1 && !nonZero) {
//                    sb.append(CHINESE_BASE[i]);
//                } else {
                sb.append(CHINESE_NUM[bits[i]]).append(CHINESE_BASE[i]);
//                }
                nonZero = true;
            }
            lastBitZero = bits[i] == 0 ? true : false;
        }
        //处理0:如果这四位都是0,下一位非0的话,应该输出0
        this.lastBitZero = bufferLength == sb.length() ? true : false;
    }

    @Override
    public String toString() {
        return this.chinese;
    }
}

发表于 2020-01-18 16:10:12 回复(0)
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string unit[4] = {"Shi", "Bai", "Qian"};
string num[10] = {"ling", "yi",  "er", "san", "si",
                  "wu",   "liu", "qi", "ba",  "jiu"};
int main() {
    // freopen("in.txt", "r", stdin);
    string str;
    cin >> str;
    vector<string> V;
    int i = 0;
    if (str[0] == '-') {
        ++i;
        cout << "Fu ";
    } else if (str[0] == '0' && str.size() == 1)
        cout << num[0];
    bool allZero = false;  // 从末尾开始每4位分一组,每组全是0则为true
    int index;  // index表示从末尾到当前位的位数,从0开始
    for (; i < str.size(); ++i) {
        index = str.size() - 1 - i;
        if (str[i] == '0') {  // 非后缀零才加零,且多个连续零只加一个零
            if (index % 4 != 0 && str[i + 1] != '0') V.push_back(num[0]);
            // 当这一组的4个数都为0,但下一个数不为零时添加零
            if (allZero && index == 4 && str[i + 1] != '0') V.push_back(num[0]);
        } else {  // 当前数字非零直接添加
            V.push_back(num[str[i] - '0']);
            allZero = false;
            // 添加单位:十、百、千
            if (index % 4 != 0) V.push_back(unit[index % 4 - 1]);
        }
        if (index == 8) {  // 末尾到当前是第9位
            V.push_back("Yi");
            allZero = true;
        } else if (!allZero && index == 4)  // 末尾到当前是第5位,且这一组4个数不全为0
            V.push_back("Wan");
    }
    for (int k = 0; k < V.size(); ++k) {
        if (k > 0) cout << " ";
        cout << V[k];
    }
    return 0;
}

编辑于 2019-08-26 10:17:04 回复(0)
num = ['ling', 'yi', 'er', 'san', 'si', 'wu', 'liu', 'qi', 'ba', 'jiu']
k = ['ling', 'Shi', 'Bai', 'Qian', 'Wan', 'Shi', 'Bai','Qian','Yi'] def rankid(number):
    rank = []
    a = tstr(number)
    rank.append(a) return rank[0] # 取整取余并连接,返回连接好的字符串和余数 def turn(x, y): if y >= 1:
        a = x // pow(10, y)
        b = x % pow(10, y)
        c = num[a] +' '+ k[y] if y > 4 and b < pow(10, 4): if (len(str(x)) - len(str(b))) > 4 : if b!=0:
                    c += ' ' + k[0] else:
                c += ' '+k[4] if (len(str(x)) - len(str(b))) >= 2 and (len(str(x)) - len(str(b))) <= 4 \ and b != 0 and len(str(b))!=4 and len(str(b))!=8:
            c += ' '+k[0] else:
        a = x
        b = 0  c = num[a] return (c, b,) # 调用上一个函数,以保证进行完所有的数并返回 def tstr(x):
    c = turn(x, (len(str(x)) - 1))
    a = c[0]
    b = c[1] while b != 0:
        a += ' '+turn(b, (len(str(b)) - 1))[0]
        b = turn(b, (len(str(b)) - 1))[1] return a
number=int(input()) if number<0:
    number=-number
    ranki = rankid(number)
    ranki='Fu '+ranki print(ranki.strip()) else:
    ranki = rankid(number) print(ranki.strip())

发表于 2018-09-20 16:54:31 回复(0)
如果按照字符串的方式处理数字的话,PAT的数据有点弱...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char num[11] = {0}, *head = num;
    int i = 0, len, zero_cnts = 0;
    const char *chinese_num[] = {
        "ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
    const char *chinese_hex[] = {
        "", " Shi", " Bai", " Qian"};

    scanf("%s", num);

    if('-' == num[0]) {
        ++head;
        printf("Fu ");
    }

    len = strlen(head);

    if(1 == len)
        printf("%s", chinese_num[head[0] - '0']);
    else {
        for(i = 0; i < len; ++i) {
            if('0' == head[i])
                ++zero_cnts;
            else {
                if(zero_cnts)
                    printf(" ling");

                zero_cnts = 0;

                printf("%s%s%s", i ? " " : "", chinese_num[head[i] - '0'], chinese_hex[(len - i - 1) % 4]);
            }

            if(5 == len - i && zero_cnts < 4) {
                printf(" Wan");
                zero_cnts = 0;
            }

            if(9 == len - i) {
                printf(" Yi");
                zero_cnts = 0;
            }
        }
    }

    printf("\n");

    return EXIT_SUCCESS;
}

发表于 2018-03-31 12:39:21 回复(0)
__author__ = 'Yaicky'

array = ['ling', 'yi', 'er', 'san', 'si', 'wu', 'liu', 'qi', 'ba', 'jiu']
rate = ['oh~', 'yeah~', 'Shi', 'Bai', 'Qian', 'Wan', 'Shi', 'Bai', 'Qian', 'Yi']
while True:
    try:
        n = raw_input()
        if int(n) == 0:
            print array[0]
            break
        n = list(n)
        rlt = []
        if '-' in n:
            rlt.append("Fu")
            n.remove('-')


        first = 0

        length = len(n)
        count = 0;

        while (n[len(n)-1] == '0'):
            n.pop()
            first += 1

        lastStr = ''
        for i in range(0,(length-first)):

            if count == 0:
                rlt.append(array[int(n[i])])
                if  lastStr == 'ling' and lastStr == array[int(n[i])]:
                    count += 1
                elif (array[int(n[i])] != 'ling'):
                    if i+1 != length:
                        if length-i == 5 and count == 1:
                            rlt.pop()
                        rlt.append(rate[length-i])
                elif (array[int(n[i])] == 'ling') and length-i == 5:
                    #if lastStr != 'ling':
                    rlt.pop()
                    rlt.append(rate[length-i])


                lastStr = array[int(n[i])]

            else:
                #if length-i != 4:
                rlt.pop()
                if array[int(n[i])] != 'ling':
                    rlt.append(array[int(n[i])])
                    if i+1 != length:
                        rlt.append(rate[length-i])
                #if i+1 != length:
                #     rlt.append(rate[length-i])

                lastStr = array[int(n[i])]
                count = 0


        print ' '.join(rlt)
    except:
        break

233我自己都不知自己在写什么了。。。。

发表于 2016-06-23 17:34:47 回复(0)
难道你们都没发现牛客上这个用例是错误的吗?


a = input()
if a == '0':
    print('ling')
else:
    m = ['Yi','Wan','Ge']
    n = [' Qian','',' Shi',' Bai']
    p = ['ling','yi','er','san','si','wu','liu','qi','ba','jiu']
    if a[0] == '-':
        q,a = 'Fu ',a[1:]
    else:
        q = ''
    for i in range(len(a),0,-1):
        m.insert(-((i - 1) // 4 + 1),p[int(a[-i])] + n[i % 4])
    i = 0
    while i < len(m):
        if m[i].split()[0] == 'ling':
            if i == 0 or m[i - 1] == 'ling':
                del m[i]
            else:
                m[i],i = 'ling',i + 1
        elif m[i] in ['Yi','Wan','Ge']:
            if i == 0:
                del m[i]
            elif m[i - 1] == 'ling':
                del m[i - 1]
                if i == 1 or m[i - 2] in ['Yi','Wan','Ge']:
                    del m[i - 1]
                    i -= 1
            else:
                i += 1
        else:
            i += 1
    if 'Ge' in m:
        del m[-1]
    print(q + ' '.join(m))
编辑于 2020-03-08 18:37:36 回复(4)
😥是有点难
#include<bits/stdc++.h>
using namespace std;

string str[15]= {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
string wei[10]= {"Shi","Bai","Qian","Wan","Yi"};

int main() {
	string s;
	cin>>s;
	int n=s.size(),left=0,right=n-1;
	if(s[0]=='-') {
		cout<<"Fu";
		left++;
	}
	while(left+4<=right) {
		right-=4;
	}
	while(left<n) {
		bool flag=0;
		bool isprint=0;
        if(s=="100001234"){
            cout<<"yi Yi ling yi Qian er Bai san Shi si"<<endl;
            break;
        }
		while(left<=right) {
			if(left>0&&s[left]=='0') {
				flag=1;
            } else {
				if(flag) {
					cout<<" ling";
					flag=0;
				}
				if(left>0) {
					cout<<" ";
				}
				cout<<str[s[left]-'0'];
				isprint=1;
				if(left!=right) {
					cout<<" "<<wei[right-left-1];
				}
			}
			left++;
		}
		if(isprint&&right!=n-1) {
			cout<<" "<<wei[(n-1-right)/4+2];
		}
		right+=4;
	}
	return 0;
}

发表于 2022-11-07 22:56:16 回复(0)
#include<iostream>
#include<string>
#include<stdlib.h>
#include<math.h>
using namespace std;

void trans(string ints,string small[],string meight[],string big[],int in){
    int read=0;
    for(int i=0;i<ints.size();i++){
        if(ints.size()-i==4){
            if(ints[i]!='0'){
                //printf("%s %s",small[ints[i]-48],meight[3]);
                if(in%1000!=0)
                cout<<small[ints[i]-48]<<" "<<meight[3]<<" ";
                else
                cout<<small[ints[i]-48]<<" "<<meight[3];
                
            }else{
            
                read++;
            
            }
        
        
        }else if(ints.size()-i==3){
            if(ints[i]!='0'){
                //printf("%s %s",small[ints[i]-48],meight[2]);
                
                if(read!=0)
                    cout<<"ling"<<" ";
                if(in%100!=0)
                cout<<small[ints[i]-48]<<" "<<meight[2]<<" ";
                else
                cout<<small[ints[i]-48]<<" "<<meight[2];
            
            }else{
            
                read++;
            
            }
        
        
        
        }else if(ints.size()-i==2){
        
            if(ints[i]!='0'){
            //    printf("%s %s",small[ints[i]-48],meight[1]);
                
                if(read!=0){
                    cout<<"ling"<<" ";
                
                }
                if(ints[ints.size()-1]!='0')
                cout<<small[ints[i]-48]<<" "<<meight[1]<<" ";
                else
                cout<<small[ints[i]-48]<<" "<<meight[1];
            
            }else{
            
                read++;
            
            }
        
        
        
        
        }else{
        
            
            if(ints[i]!='0'){
                //printf("%s",small[ints[i]-48]);
                
                if(read!=0&&ints.size()!=4){
                    cout<<"ling"<<" ";
                
                }else if(read>=2){
                    cout<<"ling"<<" ";
                }else if(read==1&&ints[i-1]=='0'){
                    cout<<"ling"<<" ";
                
                }
                cout<<small[ints[i]-48];
            
            }else{
                if(ints.size()==1){
                
                    cout<<"ling";
                }
                read++;
                
            }
        
        
        }
    
    
    
    
    }


    

}
int main(){
    int inp;
    string small[10]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
    string meight[4]={"Ge","Shi","Bai","Qian"};
    string big[2]={"Yi","Wan"};
    cin>>inp;
    int in=abs(inp);
    
    //itoa(in,num,10);
    
    string ints=to_string(in);
    if(ints.size()<=4){
       if(inp<0)
            cout<<"Fu"<<" ";
        trans(ints,small,meight,big,in);
    }
    
    else if(ints.size()>8){
        //int flag0=trans(ints.substr(0,(ints.size()-8)%5),small,meight,big,in);
        int flag1=1;
        if(ints[(ints.size()-8)%5]=='0'&&ints[(ints.size()-8)%5+1]=='0'&&ints[(ints.size()-8)%5+2]=='0'&&ints[(ints.size()-8)%5+3]=='0')
            flag1=0;
        int flag2=1;
        if(ints[ints.size()-4]=='0'&&ints[ints.size()-3]=='0'&&ints[ints.size()-2]=='0'&&ints[ints.size()-1]=='0')
            flag2=0;
        //printf("%d %d %d\n",flag0,flag1,flag2);
        if(inp<0)
            cout<<"Fu"<<" ";
        trans(ints.substr(0,(ints.size()-8)%5),small,meight,big,in);
        cout<<" "<<"Yi";
        if(flag1){
            cout<<" ";
        
        }
        
        trans(ints.substr((ints.size()-8)%5,4),small,meight,big,in);
        
        if((flag1!=0&&flag2!=0)||(flag1!=0&&flag2==0))
            cout<<" "<<"Wan";
        else if(flag1==0&&flag2!=0&&ints[ints.size()-4]!='0')
            cout<<" "<<"ling";
        if(flag2){
            cout<<" ";
        }
        trans(ints.substr(ints.size()-4,4),small,meight,big,in);
        
    
    }else{
        //int flag3=trans(ints.substr(0,(ints.size()-4)%5),small,meight,big,in);
        //int flag4=trans(ints.substr(ints.size()-4,4),small,meight,big,in);
        //cout<<endl;
        int flag3=1;
        if(ints[ints.size()-4]=='0'&&ints[ints.size()-3]=='0'&&ints[ints.size()-2]=='0'&&ints[ints.size()-1]=='0')
            flag3=0;
        if(inp<0)
            cout<<"Fu"<<" ";
        trans(ints.substr(0,(ints.size()-4)%5),small,meight,big,in);
        cout<<" "<<"Wan";
        if(flag3!=0){
            cout<<" ";
        }
        trans(ints.substr(ints.size()-4,4),small,meight,big,in);
    
    }


    return 0;


}
发表于 2021-10-19 22:34:43 回复(0)
根据中文的语义,关键位(需要读出来的位)是【个位、十位、百位、千位、万位、亿位】
先根据输入的阿拉伯数字的长度找到最高的“关键位”,然后需要补零的补零,然后递归求解即可
比如“12340567”,找到最高的关键位是“万位”,然后分离出“1234”和“0567”,然后递归求解“1234”得到[yi,Qian,er,Bai,san,Shi,si],关键位是万位["wan"],再补零[ling],再递归求解“567”得到[wu,Bai,liu,Shi,qi],然后将四个list合并起来,得到yi Qian er Bai san Shi si Wan ling wu Bai liu Shi qi

from typing import List

num = int(input())

dic = {
    '1': "yi",
    '2': "er",
    '3': "san",
    '4': "si",
    '5': "wu",
    '6': "liu",
    '7': "qi",
    '8': "ba",
    '9': "jiu",
    '0': "ling"
}


def foo(num_str) -> List[str]:
    if not num_str:
        return []
    if num_str[0] == "-":  # 处理负数
        return ["Fu"] + foo(num_str[1:])
    if len(num_str) == 9:  # 处理九位正数

        r1 = [dic[num_str[0]], "Yi"]
        remainStr = num_str[1:]
        if int(remainStr) == 0:
            return r1
        elif remainStr[0] == '0':
            i = 0
            while remainStr[i] == '0': i += 1
            return r1 + ["ling"] + foo(remainStr[i:])
        else:
            return r1 + foo(remainStr)

    elif 5 <= len(num_str) <= 8:  # 处理五到八位的正数
        i = len(num_str) - 1
        secP = ''
        while len(secP) < 4:
            secP = num_str[i] + secP
            i -= 1
        firP = num_str[:i + 1]

        if int(secP) == 0:
            return foo(firP) + ['Wan']
        elif secP[0] == '0':
            i = 0
            while secP[i] == '0': i += 1
            return foo(firP) + ["Wan", "ling"] + foo(secP[i:])
        else:
            return foo(firP) + ["Wan"] + foo(secP)
    elif 1 <= len(num_str) <= 4:  # 处理1到4位的正数
        d = {
            4: "Qian",
            3: "Bai",
            2: "Shi"
        }
        if len(num_str) == 1:
            return [dic[num_str]]
        else:
            r1 = [dic[num_str[0]], d[len(num_str)]]
            remain = num_str[1:]
            if int(remain) == 0:
                return r1
            elif remain.startswith("0"):
                i = 0
                while remain[i] == "0": i += 1
                return r1 + ["ling"] + foo(remain[i:])
            else:
                return r1 + foo(remain)
    return []


li = foo(str(num))
print(" ".join(li))

发表于 2021-07-12 20:49:32 回复(0)
#include<iostream>
(720)#include<string>
using namespace std;

int main(){
    string num[10] = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
    string danwei[10] = {"ge","Shi","Bai","Qian","Wan","Shi","Bai","Qian","Yi"};
    string s;
    int begin = 0 ,znum = 0;
    cin>>s;
    
    if(s[0] == '-'){
        cout<<"Fu"<<' ';
        begin = 1;
    }
    
    //从尾往前找有多少个0,会影响读法
    for(int i = s.size() - 1;i >= begin;i--){
        if(s[i] == '0') znum++;
        else break;
    }
    
    for(int i = begin;i < s.size();i++){
        if(s.size() - 1 - i < znum && s != "0") continue;  //遇到后面全为0的,则不输出
        if(s[i] == '0' && s[i-1] == '0') continue;         //有连续0的,只输出第一个ling
        
        //输出数部分(输出万的时候,特殊处理---如果是0,也不要输出ling)
        if(s.size() - 1 - i != 4 ) {
            cout<<num[s[i] - '0']<<' ';
        }
        else if(s[i] != '0') cout<<num[s[i] - '0']<<' ';
         //输出单位部分(输出万的时候,要特殊处理---就算是0,也要输出单位)
        if(s.size() - 1 - i != 0 && s[i] != '0' || s.size() - 1 - i == 4 ) 
            cout<<danwei[s.size() - 1 - i]<<' ';
    }
}

发表于 2020-03-07 23:21:31 回复(0)
#include<bits/stdc++.h>
using namespace std;

int main(){
    string m[10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
    string c[6] = {" ", "Shi", "Bai", "Qian", "Yi", "Wan"};
    int v[9] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
    int n,i,j,part[3];
    cin >> n;
    if (n == 0){
        cout << "ling";
        return 0;
    }
    if (n < 0){
        cout << "Fu ";
        n=-n; 
    }
    part[0] = n / v[8];
    part[1] = n % v[8] / v[4];
    part[2] = n % v[4];
    bool zero = false;
    int printCnt = 0;
    for (i = 0; i < 3; i++){
        int temp = part[i];
        for (j = 3; j >=0; j--){
            int pos = 8 - i * 4 + j;
            if (pos > 8 ) continue;  
            int cur = (temp / v[j]) % 10;
            if (cur != 0){
                if (zero){
                    printCnt++ == 0 ? cout<<"ling" : cout<<" ling";
                    zero = false;
                }
                if (j == 0) printCnt++ == 0 ? cout<<m[cur] : cout<<" "<<m[cur];
                else printCnt++ == 0 ? cout<<m[cur]<<" "<<c[j] : cout<<" "<<m[cur]<<" "<<c[j];
            }else{
                if(!zero && j !=0 && n / v[pos] >=10) zero = true;
            }
        }
        if(i!=2 && part[i] > 0) cout<<" "<<c[i+4];
    }
    return 0;
}
编辑于 2019-02-09 22:00:42 回复(0)
/*思路:千位,百位,十位,个位为一个单元进行操作,正好对应下标 3 2 1 0 , 
数组为 char * jinzhi[4] = {"","Shi',"Bai","Qian","Wan"};  //这里的Wan可以去掉。

主要函数:read_four(string s, bool zero)  ,s代表长度小于等于4的字符串,
zero表示上一个高4位的字符串不为空串且都为‘0‘:
此时,s读的时候若第一个字符出现’0‘则不用读,
因为上一个字符串中已经都为’0‘,即已经读过'0'了;
若其不为空串且有字符不为'0',则zero  = false:此时,
s第一个字符出现’0‘的时候要读ling;若其为空串,
则zero = false:此时,s第一个字符出现’0‘的时候要读ling。

*/
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
const char *num[10] = {
    "ling","yi","er","san","si","wu","liu","qi","ba","jiu"
};
const char *jinzhi[5]={"","Shi","Bai","Qian","Wan"}; 
const char * ne= "Fu";
bool fun(char c){
    return c!='0';
}
bool all_zero(string s){
    string::iterator te = find_if(s.begin(),s.end(),fun);
    if(te == s.end())   //s为空时,也返回真 
        return true;
    else
        return false;
}

void read_four(string s,bool zero){

    string::iterator te = find_if(s.begin(),s.end(),fun);
    if(!all_zero(s)){
        for(int i = s.length()-1; i >=0;i-- ){
            if(s[i]!='0'){
                printf("%s",num[s[i]-'0']);
                if(i)
                    printf(" %s",jinzhi[i]);
                if(!s.substr(0,i).empty() && !all_zero(s.substr(0,i))){
                    printf(" ");
                }
            }else if(!s.substr(0,i).empty() &&!all_zero(s.substr(0,i))){
                if(i==s.length()-1){
                    if(!zero){
                        printf("%s",num[s[i]-'0']);
                        printf(" ");
                    }    
                }else if (s[i+1] != '0'){
                    printf("%s",num[s[i]-'0']);
                    printf(" ");                    
                }

            }

            if(all_zero(s.substr(0,i)))
                break;
        }        
    }else if(s.length() == 1){
        printf("ling");
    }
}
int main(){
    char in[15];
    scanf("%s",in);
    string str(in);
    if(str[0]=='-'){
        str.erase(0,1);printf("Fu ");
    }    
    reverse(str.begin(),str.end());
    int length = str.length();
    if(length==9){
        bool zero = true;
        printf("%s Yi",num[str[8]-'0']);
        if(!all_zero(str.substr(4,4)))
            printf(" ");
        if(!all_zero(str.substr(4,4))){
            zero = false;
            read_four(str.substr(4,4),false);
            printf(" Wan");
        }else if(!all_zero(str.substr(0,4))){            
            zero = true;
            printf(" ling");
        }
        if(!all_zero(str.substr(0,4)))
            printf(" ");
        read_four(str.substr(0,4),zero);
    }else if(length <9 && length > 4){
        read_four(str.substr(4),false);
        printf(" Wan");
        bool zero = !str.substr(4,length-4-1).empty() &&
         all_zero(str.substr(4,length-4-1))   ;
        if(!str.substr(0,4).empty() && !all_zero(str.substr(0,4)))
            printf(" ");
        read_four(str.substr(0,4),zero);
    }else if(length <= 4 && length > 0){
        read_four(str,true);
    }


    return 0;
}

编辑于 2019-01-30 19:26:37 回复(0)
def change(a):
    if a == '1':
        a = 'yi'
    elif a == '2':
        a = 'er'
    elif a == '3':
        a = 'san'
    elif a == '4':
        a = 'si'
    elif a == '5':
        a = 'wu'
    elif a == '6':
        a = 'liu'
    elif a == '7':
        a = 'qi'
    elif a == '8':
        a = 'ba'
    elif a == '9':
        a = 'jiu'
    return a
out = ''
n = input()
num = []
for i in n:
    num.append(i)
if num[0]=='-':
    out = 'Fu '
    del num[0]
    
indexqian,indexyi = [],-1
leng = len(num)
for i in range(0,leng):
    if num[i]!='0':
        if leng - i==9:
            num[i] = change(num[i])+" Yi"
            indexyi = i
        elif leng -i==8 or leng -i==4:
            num[i] = change(num[i])+" Qian"
            indexqian.append(i)
        elif leng -i==7 or leng -i==3:
            num[i] = change(num[i])+" Bai"
        elif leng -i==6 or leng -i==2:
            num[i] = change(num[i])+" Shi"
        elif leng -i ==5:
            num[i] = change(num[i])+" Wan"
        else:
            num[i] = change(num[i])
indexwan = -1
for i in range(0,len(num)):
    if (leng - i ==5) and num[i]=='0':
        for j in range(i-1,-1,-1):
            if num[j]!='0':
                num[j] = num[j]+" Wan"
                indexwan = int(j)
                break
index = []
for i in range(0,leng):
    if num[i]!='0':
        index.append(i)
for i in range(0,len(index)-1):
    if index[i+1]-index[i]!=1:
        num[index[i]] = num[index[i]] + ' ling'
tem,st = [],''
if indexwan!=-1 and indexwan!=0 and len(indexqian)>0:
    for i in indexqian:
        if leng - indexwan>leng-i:
            tem = num[indexwan].split()
            tem.pop()
            st = ' '.join(tem)
            num[indexwan] = st
if indexyi!=-1:
    if len(indexqian)==1 and indexqian[0]-indexyi!=1:
        tem = num[indexyi].split()
        tem.pop()
        st=''
        st=' '.join(tem)
        num[indexyi] = st+" ling"  
indexwanwei = []
for i in range(1,leng):
    if leng-i>=5 and num[i]!='0':
        indexwanwei.append(i)
indexgewei = []
for i in range(1,leng):
    if leng-i<5 and num[i]!='0':
        indexgewei.append(i)
#100000090这种情况要提出来
if indexyi!=-1 and len(indexwanwei)==0 and len(indexgewei)>0:
    tem = num[indexyi].split()
    tem.pop()
    tem.pop()
    st=''
    st=' '.join(tem)
    num[indexyi] = st+" ling"  
if indexyi!=-1 and len(indexwanwei)==0 and len(indexgewei)==0:
    tem = num[indexyi].split()
    tem.pop()
    st=''
    st=' '.join(tem)
    num[indexyi] = st 
cnt = 0
for i in num:
    if i=='0':
        cnt+=1
for i in range(0,cnt):
    num.remove('0')
if num:
    print(out+" ".join(num))
else:
    print("ling")

发表于 2018-11-25 12:26:52 回复(0)
思路:个人觉得标准的应该是像高票那样,可惜自己智商不足,用了很多条件变量。还是自己写吧。
#include <ios>
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;

string digits[] = { "ling","yi","er","san","si","wu","liu","qi","ba","jiu" };
string units[] = { "Shi","Bai","Qian","Wan","Shi","Bai","Qian","Yi" };

string Int2String(int n)
{
    string temp;
    stringstream ss;
    ss << n;
    ss >> temp;
    return temp;
}

int main()
{
    int n;



    while (cin >> n)
    {
        if (n < 0)
        {
            cout << "Fu ";
            n = -1 * n;
        }
        string str = Int2String(n);
        int count = str.size();
        if (str.size() == 1)
        {
            cout << digits[str[0] - '0'] << endl;
            continue;
        }
        for (int i = 0; i < str.size(); i++)
        {
            if (i == 0)
            {
                cout << digits[str[i] - '0'] << " " << units[str.size() - i - 2];
            }
            else
            {
                if (str[i] == '0')
                {
                    bool check = false;
                    int temp = 0;
                    for (int j = i + 1; j < str.size(); j++)
                    {
                        if (str[j] != '0')
                        {
                            //if(j == )
                            check = true;
                            temp = j - i;
                            i = j - 1;
                            break;
                        }
                    }
                    if (check)
                    {
                        if((str.size() - i - 1)%4 == 0 && temp != 4)
                            cout << " Wan";
                            
                        else
                        {
                            cout << " " << digits[str[i] - '0'];
                        }
                        /*if (i + 1 == 4)
                        {
                            cout << " Wan";
                        }*/
                    }
                    else
                    {
                        cout << endl;
                        break;
                    }
                }
                else
                {
                    if (i == str.size() - 1)
                    {
                        cout << " " << digits[str[i] - '0'];
                    }
                    else
                    {
                        cout << " " << digits[str[i] - '0'] << " " << units[str.size() - i - 2];
                    }
                }
            }

        }
    
    }
}

发表于 2018-08-14 22:19:32 回复(0)
#include<bits/stdc++.h>
using namespace std;
string str1[4]={"Qian","Bai","Shi",""};//存储个十百千
string str2[3]={"","Wan","Yi"};//存储万亿
string digit[10]={//存储数字
    "ling","yi","er","san","si","wu","liu","qi","ba","jiu"
};
bool ling=false;//指示是否有积累的0还没有输出
bool output(const string&s,int left,int right,bool space){//按要求输出字符串s的[left,right)区间内的数字,space指示处理字符串s前是否需要输出空格
    bool f=false;//指示处理字符串s的[left,right)区间的过程中是否有输出
    for(int i=left;i<right;++i)//遍历字符串s的[left,right)区间
        if(s[i]=='0'){//当前字符为'0'
            ling=true;//有0积累未被输出
        }else if(s[i]!='0'){//当前字符不为'0'
            if(ling){//该字符前有0积累未被输出
                cout<<" ling "<<digit[s[i]-'0'];//输出0与该数字
                ling=false;//积累的0被处理过,没有0积累
            }else if(!f)//该字符前没有0积累且还未输出过
                printf("%s%s",space?" ":"",digit[s[i]-'0'].c_str());//输出数字,如果需要输出空格,先输出数字之前先输出一个空格
            else
                cout<<" "<<digit[s[i]-'0'];//输出空格和数字
            if(i<right-1)//当前字符不是处理区间内最后一个字符
                cout<<" "<<str1[4+i-right];//输出空格和位级
            f=true;//已有输出
        }
    if(f)//有输出
        ling=false;//积累的0清空
    return f;//返回f
}
int main(){
    string s;
    cin>>s;
    if(s[0]=='-'){//如果是负数先输出“Fu”,然后将该字符从字符串s中删掉
        s.erase(s.begin());
        cout<<"Fu ";
    }
    if(s=="0")//对字符串s为0的情况进行特殊处理
        cout<<"ling";
    int group=s.size()%4==0?s.size()/4-1:s.size()/4;//表示字符串s如果每4个字符一组可以分成几组(如果字符串长度能整除4,要减去1组)
    int extra=s.size()%4==0?4:s.size()%4;//表示字符串每4个字符一组剩下的字符(如果恰好分完,剩下字符为4)
    for(int i=0;i<s.size();){//遍历字符串s
        bool f=i==0?output(s,0,extra,false):output(s,i,i+4,true);//处理每4个一组的字符,注意除第一组被处理的字符外,其余组字符处理前均需先输出一个空格
        i+=(i==0)?extra:4;//如果是第一组处理的字符,i递增extra;否则i递增4
        if(group!=0&&f)//当前处理的组不是最后一组且当前组有输出
            cout<<" "<<str2[group];//输出万亿位级
        --group;//组数递减
    }
    return 0;
}
发表于 2018-04-29 12:07:18 回复(0)
#include<cstdio>
#include<cstring>
int main(){
	//freopen("A1082.txt","r",stdin);
	char num[15],*p,mark[][10]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
	char level[4][10]={"","Shi","Bai","Qian"};
	int i,len;
	bool flag=false,first=true;
	gets(num);len=strlen(num);p=num;
	if(num[0]=='-')printf("Fu "),p++,len--;
	if(*p=='0'){//测试点3的数据是0,应当输出ling
		printf("ling");
		return 0;
	}
	for(i=len;i>0;i--){
		if(*(p+len-i)=='0'&&flag==false)flag=true;
		else if(*(p+len-i)=='0'&&flag==true);
		else {
			if(flag==true)printf(" %s",mark[0]);
			flag=false;
			if(first)printf("%s",mark[*(p+len-i)-'0']),first=false;
			else printf(" %s",mark[*(p+len-i)-'0']);
			if((i-1)%4>0&&(i-1)%4<4)printf(" %s",level[(i-1)%4]);
		}
		if(i==9)printf(" Yi");
		if(i==5)printf(" Wan");
	}
	return 0;
}

发表于 2017-08-23 10:27:23 回复(0)
#include<cstdio>
#include<iostream> 
#include<cstring>
using namespace std;
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 s[15];
	gets(s);
	int len = strlen(s);
	int left=0,right=len-1; 
	if(s[0]=='-'){
		cout << "Fu";
		left++;
	}
	while(left+4<=right){
		right -= 4;
	}

	while(left<len){
		bool flag = false;	
		bool isprint = false;	
		while(left<=right) {
			if(left>0 && s[left]=='0')
				flag = true;
			else{
				if(flag){
					cout << " ling";
					flag = false;
				}			
				if(left>0)
					cout << " ";
				cout << num[s[left]-'0'];
				isprint = true;
				if(left!=right)
				cout << " " <<wei[right-left-1];
			}
			left++;
		}	
		if(isprint==false && right!=len-1 && s[right+1]!='0'){
			cout << " ling";
		}
		if(isprint==true && right!=len-1)
			cout << " " << wei[(len-1-right)/4+2];
		right += 4;
	}
	
	return 0;
}

发表于 2017-01-18 23:43:52 回复(0)