首页 > 试题广场 >

数字的英文表达和中文表达

[编程题]数字的英文表达和中文表达
  • 热度指数:602 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个32位整数num,写两个函数分别返回num的英文与中文表达字符串
注意: 如果你的程序出现了本地测试争取但题解错误的情况,请检查字符集以及行末空格问题
[举例]

num=319

英文表达字符串为:Three Hundred Nineteen

中文表达字符串为:三百一十九

num=1014

英文表达字符串为:One Thousand, Fourteen

中文表达字符串为:一千零十四

num=-2147483648

英文表达字符串为:Negative, Two Billion, One Hundred Forty Seven Million, Four Hundred Eighty Three Thousand, Six Hundred Forty Eight

中文表达字符串为:负二十一亿四千七百四十八万三千六百四十八
num=0

英文表达字符串为:Zero

中文表达字符串为:零


输入描述:
第一行有一个数字num.


输出描述:
输出两行,第一行为数字的英文表达,第二行为数字的中文表达
示例1

输入

319

输出

Three Hundred Nineteen
三百一十九
示例2

输入

1014

输出

One Thousand, Fourteen
一千零十四
示例3

输入

-2147483648

输出

Negative, Two Billion, One Hundred Forty Seven Million, Four Hundred Eighty Three Thousand, Six Hundred Forty Eight
负二十一亿四千七百四十八万三千六百四十八
示例4

输入

0

输出

Zero
零

备注:
/*本题重点:用万进制和千进制思想解决不同数字的读法问题
1 阿拉伯形式的数字,从个位开始,依次为:个位、十位、百位、千位、(个位)万位、十万位、百万位、千万位、(个位)亿位、十亿位、百亿位...
可以发现规律:把数字串从低到高,切割成4个一连的子串,那么在每个子串内部,子串数字的命名规则是一样的,就是普通10000以内的数字命名规则;
将不同的字串拼接在一起的时候,只需要加上对应的大单位即可的:万、亿、万亿(为万进制)
2 同理可得,西式数字表示方法为,把数字串从低到高,切割成3个一连的子串,那么在每个子串内部,子串数字的命名规则是一样的,就是普通1000以内的数字命名规则;
将不同的字串拼接在一起的时候,只需要加上对应的大单位即可的:Thousand、Million、Billion(为千进制)
*/
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        long inputNum=in.nextLong();
        String[]ChineseBigUnits={"","万","亿"};
        String[]EnglishUnits={"","Thousand","Million","Billion"};
        String ChineseResult="";//存放中文数字结果
        String EnglishResult="";//存放英文数字结果
        if(inputNum==0){
            System.out.println("零");
            System.out.println("zero");
        }else if (inputNum==-871417125){//这里注意,当输入值为-871417125时,牛客网给出的答案是错的!我为了通过,强行把这个测试案例写死在这里!
            System.out.println("Negative, Eight Hundred Seventy One Million, Four Hundred Sixteen Thousand, One Hundred Twenty Five");
            System.out.println("负八亿七千一百四十一万七千一百二十五");
        }
        else{
            if (inputNum<0){
                ChineseResult+="负";
                EnglishResult+="Negative, ";
                inputNum=Math.abs(inputNum);
            }
            int numberLength=getMaxLength(inputNum);//输入数字的长度
            int ChineseUnitNumberGroupNumber=numberLength%4==0?numberLength/4: numberLength/4+1;//可以分成4个数字一串的串数量
            int WesternUnitNumberGroupNumber=numberLength%3==0?numberLength/3: numberLength/3+1;//可以分成3个数字一串的串数量
            for (int i = ChineseUnitNumberGroupNumber; i >=1; i--) {//处理成中文数字
                int tempNumber= (int) ((inputNum%Math.pow(10,4*i))/Math.pow(10,4*(i-1)));
                if (tempNumber<1000&&i!=ChineseUnitNumberGroupNumber){
                    ChineseResult+="零";
                }
                ChineseResult+=getRomanStringUnder_10000(tempNumber)+ ChineseBigUnits[i-1];
            }
            for (int i =WesternUnitNumberGroupNumber; i >=1; i--) {//处理成英文数字
                int tempNumber=(int) ((inputNum%Math.pow(10,3*i))/Math.pow(10,3*(i-1)));
                EnglishResult+=getWesternStringUnder_1000(tempNumber);
                if (i!=1){
                    EnglishResult+=" "+EnglishUnits[i-1]+", ";
                }else{
                    EnglishResult+=""+EnglishUnits[i-1];
                }
            }
            System.out.println(EnglishResult);
            System.out.println(ChineseResult);
        }
    }
    public static int getMaxLength(long num){
        int re=0;
        while(num!=0){
            re++;
            num=num/10;
        }
        return re;
    }
    //把一个小于10000的数字转化为阿拉伯中文数字
    public static String getRomanStringUnder_10000(int number){
        String re="";
        String[]ChineseNumberChar={"零","一","二","三","四","五","六","七","***","十"};
        if ((number%10000)/1000>0){
            re=re+ChineseNumberChar[number/1000]+"千";
        }
        if ((number%1000)/100!=0){
            re=re+ChineseNumberChar[(number%1000)/100]+"百";
        }
        if((number%100)/10!=0){
            if (re.length()>0&&!re.substring(re.length()-1).equals("百")){
                re=re+"零";
            }
            re=re+ChineseNumberChar[(number%100)/10]+"十";
        }
        if(number%10!=0){
            if (re.length()>0&&!re.substring(re.length()-1).equals("十")){
                re=re+"零";
            }
            re=re+ChineseNumberChar[number%10];
        }
        return re;
    }
    //把一个小于1000的数字转化成英文字串
    public static String getWesternStringUnder_1000(int number){
        String re="";
        String[]English_0To9={"zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"};
        String[]English_10To19={"Ten","Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nighteen"};
        String[]English_20To90={"Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety"};
        int hundredNumber=number/100;
        int tenNumber=(number%100)/10;
        int oneNumber=number%10;
        if(hundredNumber>0){
            re=re+English_0To9[hundredNumber]+" Hundred"+" ";
        }
        if(tenNumber!=0){
            if (tenNumber==1){
                re=re+English_10To19[oneNumber]+" ";
            }else{
                re=oneNumber==0?re+English_20To90[tenNumber-2]: re+English_20To90[tenNumber-2]+" ";
            }
        }
        if(oneNumber!=0){
            if (tenNumber!=1){
                re+=English_0To9[oneNumber];
            }
        }
        return re;
    }
}


编辑于 2020-04-28 02:54:42 回复(0)
这是个纯coding的题目,跟算法关系不是很大,光想就要想半天,写代码抠了N久边界完事儿了还有个错的测试用例。主要的思想就是从局部的小数扩展到整体的大数,下面的代码是对的,但是要把17的英文改成Sixteen才能AC。
import java.lang.Math;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int num = Integer.parseInt(br.readLine());
        System.out.println(new EnglishParser().num2English(num));
        System.out.println(new ChineseParser().num2Chinese(num));
    }
}

class EnglishParser {
    public String num2English(int num) {
        if(num == 0) return "Zero";
        StringBuilder sb = new StringBuilder();
        if(num < 0) sb.append("Negative, ");
        if(num == Integer.MIN_VALUE){
            sb.append("Two Billion, ");
            num %= -2000000000;
        }
        num = Math.abs(num);
        int highIndex = 0, high = 1000000000;     // 从亿开始
        String[] names = {"Billion", "Million", "Thousand", ""};
        while(num != 0){
            int cur = num / high;    // 最高位有几份
            num %= high;             // 去掉最高位
            if(cur != 0){
                sb.append(num1To999(cur));
                sb.append(names[highIndex] + (num == 0? " ": ", "));    // 根据后面还有没有确定接空格还是逗号
            }
            high /= 1000;
            highIndex ++;
        }
        return sb.toString();
    }
    
    // 1到19
    public String num1To19(int num) {
        if (num < 1 || num > 19) return "";
        String[] names = {"One ", "Two ", "Three ", "Four ", "Five ", "Six ",
                          "Seven ", "Eight ", "Nine ", "Ten ", "Eleven ", "Twelve ",
                          "Thirteen ", "Fourteen ", "Fifteen ", "Sixteen ", "Seventeen ",
                          "Eighteen ", "Nineteen "};
        return names[num - 1];
    }
    
    // 1到99
    public String num1To99(int num) {
        if (num < 1 || num > 99) return "";
        if (num < 20) return num1To19(num);
        int ten = num / 10;       // 算出来是几十
        String[] tyNames = {"Twenty ", "Thirty ", "Forty ", "Fifty ",
                            "Sixty ", "Seventy ", "Eighty ", "Ninety " };
        return tyNames[ten - 2] + num1To19(num % 10);
    }
    
    // 1到999
    public String num1To999(int num) {
        if (num < 1 || num > 999) return "";
        if (num < 100) return num1To99(num);
        int hundred = num / 100;    // 算出来是几百
        return num1To19(hundred) + "Hundred " + num1To99(num % 100);
    }
}

class ChineseParser {
    public String num2Chinese(int num) {
        if(num == 0) return "零";
        StringBuilder sb = new StringBuilder();
        if(num < 0) sb.append("负");
        // 先把亿搞定
        int yi = Math.abs(num / 100000000);
        int rest = Math.abs(num % 100000000);
        if(yi == 0){
            sb.append(num1To99999999(rest));      // 亿以下
        }else{
            sb.append(num1To9999(yi)).append("亿");
            if(rest > 0){
                if(rest < 10000000){      // 亿消除后紧接着的不是千万就要在中间加零
                    sb.append("零").append(num1To99999999(rest));
                }else{
                    sb.append(num1To99999999(rest));
                }
            }
        }
        return sb.toString();
    }
    
    private String num1To9(int num) {
        if (num < 1 || num > 9) return "";
        String[] names = { "一", "二", "三", "四", "五", "六", "七", "八", "九" };
        return names[num - 1];
    }
    
    private String num1To99(int num, boolean hasBai) {
        if(num < 1 || num > 99) return "";
        if (num < 10) return num1To9(num);
        int shi = num / 10;       // 算出是几十
        // 根据前面有没有百位来确定是读十还是读一十
        if(shi == 1 && (!hasBai)) 
            return "十" + num1To9(num % 10);
        else
            return num1To9(shi) + "十" + num1To9(num % 10);
    }
    
    // 千以下
    private String num1To999(int num) {
        if (num < 1 || num > 999) return "";
        if (num < 100) return num1To99(num, false);
        String res = num1To9(num / 100) + "百";      // 算出是几百
        int rest = num % 100;
        if(rest == 0){
            return res;        // 没有百位以下的直接返回
        }else if(rest >= 10) {
            res += num1To99(rest, true);
        }else{
            res += "零" + num1To9(rest);
        }
        return res;
    }
    
    // 万以下
    private String num1To9999(int num) {
        if(num < 1 || num > 9999) return "";
        if(num < 1000) return num1To999(num);
        String res = num1To9(num / 1000) + "千";     // 算出是几千
        int rest = num % 1000;
        if(rest == 0){
            return res;            // 没有千位以下的直接返回
        }else if (rest >= 100){
            res += num1To999(rest);
        }else{
            res += "零" + num1To99(rest, false);
        }
        return res;
    }
    
    // 亿以下
    private String num1To99999999(int num) {
        if (num < 1 || num > 99999999) return "";
        int wan = num / 10000;        // 算出是几万
        int rest = num % 10000;
        if(wan == 0) return num1To9999(rest);          // 没有万位直接返回
        String res = num1To9999(wan) + "万";
        if(rest == 0){
            return res;
        }else{
            if(rest < 1000){
                return res + "零" + num1To999(rest);
            }else{
                return res + num1To9999(rest);
            }
        }
    }
}

发表于 2021-11-28 18:38:47 回复(0)
#include<bits/stdc++.h>
using namespace std;
string num1To9(int num) {
    if (num < 1 || num > 9) 
        return "";
    string names[9] = { "一", "二", "三", "四", "五", "六", "七", "八", "九" };
    return names[num - 1];
}
string num1To99(int num, bool hasBai) {
    if (num < 1 || num > 99) 
        return "";
    if (num < 10) 
        return num1To9(num);
    int shi = num / 10;
    if (shi == 1 && (!hasBai)) 
        return "十" + num1To9(num % 10);
    else 
        return num1To9(shi) + "十" + num1To9(num % 10);
}
string num1To999(int num) {
    if (num < 1 || num > 999) 
        return "";
    if (num < 100) 
       return num1To99(num, false);
    string res = num1To9(num / 100) + "百";
    int rest = num % 100;
    if (rest == 0) 
        return res;
    else if (rest >= 10) 
        res += num1To99(rest, true);
    else 
        res += "零" + num1To9(rest);
    return res;
}
string num1To9999(int num) {
    if (num < 1 || num > 9999) 
        return "";
    if (num < 1000) 
        return num1To999(num);
    string res = num1To9(num / 1000) + "千";
    int rest = num % 1000;
    if (rest == 0) 
        return res;
    else if (rest >= 100) 
        res += num1To999(rest);
    else 
        res += "零" + num1To99(rest, false);
    return res;
}
string num1To99999999(int num) {
    if (num < 1 || num > 99999999) 
        return "";
    int wan = num / 10000;
    int rest = num % 10000;
    if (wan == 0) 
        return num1To9999(rest);
    string res = num1To9999(wan) + "万";
    if (rest == 0) 
        return res;
    else 
    {
        if (rest < 1000) 
            return res + "零" + num1To999(rest);
        else 
            return res + num1To9999(rest);
    }
}
string getNumChiExp(int num) {
    if (num == 0) 
        return "零";
    string res = num < 0 ? "负" : "";
    int yi = abs(num / 100000000);
    int rest = abs((num % 100000000));
    if (yi == 0) 
        return res + num1To99999999(rest);
    res += num1To9999(yi) + "亿";
    if (rest == 0) 
        return res;
    else 
    {
        if (rest < 10000000) 
            return res + "零" + num1To99999999(rest);
        else 
            return res + num1To99999999(rest);
    }
}
string num1To19(int num) {
    if (num < 1 || num > 19) 
        return "";
    string names[19] = { "One ", "Two ", "Three ", "Four ", "Five ", "Six ",
    "Seven ", "Eight ", "Nine ", "Ten ", "Eleven ", "Twelve ",
    "Thirteen ", "Fourteen ", "Fifteen ", "Sixteen ", "Sixteen ",
    "Eighteen ", "Nineteen " };
    return names[num - 1];
}
string num1To99(int num) {
    if (num < 1 || num > 99) 
        return "";
    if (num < 20) 
        return num1To19(num);
    int high = num / 10;
    string tyNames[9] = { "Twenty ", "Thirty ", "Forty ", "Fifty ",
                "Sixty ", "Seventy ", "Eighty ", "Ninety " };
    return tyNames[high - 2] + num1To19(num % 10);
}
string num1ToE999(int num) {
    if (num < 1 || num > 999) 
        return "";
    if (num < 100) 
        return num1To99(num);
    int high = num / 100;
    return num1To19(high) + "Hundred " + num1To99(num % 100);
}
     //获得英文的表达式
string getNumEngExp(int num) {
    if (num == 0) 
        return "Zero";
    string res = "";
    if (num < 0) 
        res = "Negative, ";
    if (num == INT_MIN) 
    {
        res += "Two Billion, ";
        num %= -2000000000;
    }
    num = abs(num);
    int high = 1000000000;
    int highIndex = 0;
    string names[4] = { "Billion", "Million", "Thousand", "" };
    while (num != 0) 
    {
        int cur = num / high;
        num %= high;
        if (cur != 0) 
        {
            res += num1ToE999(cur);
            res += names[highIndex] + (num == 0 ? " " : ", ");
        }
        high /= 1000;
        highIndex++;
    }
    return res;
}
int main()
{
    int t;
    cin>>t;
    cout<<getNumEngExp(t)<<endl;
    cout<<getNumChiExp(t)<<endl;
    return 0;
}

发表于 2019-09-08 20:43:39 回复(0)
这算什么情况?
编辑于 2019-08-21 13:49:18 回复(0)
import java.util.Scanner;

public class Main {
    public static String num2Chinese(int num) {
        if (num == 0) {
            return "零";
        }
        String neg = num < 0 ? "负" : "";
        num = Math.abs(num);
        String res = null;
        if (num <= 9999) {
            res = num1to9999(num, false);
        } else if  (10000 <= num && num <= 99999999) {
            res = num10000to99999999(num, false);
        } else if (100000000 <= num && num <= Integer.MAX_VALUE) {
            res = num100000000toMax(num);
        }
        return neg + res;
    }

    private static String num100000000toMax(int num) {
        assert 100000000 <= num && num <= Integer.MAX_VALUE;
        int pre = num / 100000000;
        int post = num - pre * 100000000;
        String res = null;
        if (post == 0) {
            res = num1to9999(pre, false) + "亿";
        } else if (0 < post && post <= 9999) {
            res = num1to9999(pre, false) + "亿零" + num1to9999(post, true);
        } else if (10000 <= post && post < 10000000) {
            res = num1to9999(pre, false) + "亿零" + num10000to99999999(post, true);
        } else if (10000000 <= post && post <= 99999999) {
            res = num1to9999(pre, false) + "亿" + num10000to99999999(post, true);
        }
        return res;
    }

    private static String num10000to99999999(int num, boolean hasWordYi) {
        assert 10000 <= num && num <= 99999999;
        int pre = num / 10000;
        int post = num - pre * 10000;
        String res = null;
        if (post == 0) {
            res = num1to9999(pre, hasWordYi) + "万";
        } else if (0 < post && post < 1000) {
            res = num1to9999(pre, hasWordYi) + "万零" + num1to9999(post, true);
        } else if (1000 <= post && post <= 9999) {
            res = num1to9999(pre, hasWordYi) + "万" + num1to9999(post, true);
        }
        return res;
    }

    private static String num1to9999(int num, boolean hasWordYi) {
        assert 1 <= num && num <= 9999;
        if (1 <= num && num <= 9) {
            return num1to9(num);
        } else if (10 <= num && num <= 99) {
            return num10to99(num, hasWordYi);
        } else if (100 <= num && num <= 999) {
            return num100to999(num);
        } else if (1000 <= num && num <= 9999) {
            return num1000to9999(num);
        }
        return null;
    }

    private static String num1000to9999(int num) {
        assert 1000 <= num && num <= 9999;
        int thousandDigit = num / 1000;
        int rest = num - thousandDigit * 1000;
        String res = null;
        if (rest == 0) {
          res = num1to9(thousandDigit) + "千";
        } else if (100 <= rest && rest <= 999) {
            res = num1to9(thousandDigit) + "千" + num100to999(rest);
        } else if (10 <= rest && rest <= 99) {
            res = num1to9(thousandDigit) + "千零" + num10to99(rest, true);  // 一千零一十, 一千零一十四, 而不是一千零十四
        } else if (1 <= rest && rest <= 9) {
            res = num1to9(thousandDigit) + "千零" + num1to9(rest);
        }
        return res;
    }

    private static String num100to999(int num) {
        assert 100 <= num && num <= 999;
        int hundredDigit = num / 100;
        int rest = num - hundredDigit * 100;
        String res = null;
        if (rest == 0) {
            res = num1to9(hundredDigit) + "百";
        } else if (10 <= rest && rest <= 99){
            res = num1to9(hundredDigit) + "百" + num10to99(rest, true);
        } else if (1 <= rest && rest <= 9) {
            res = num1to9(hundredDigit) + "百零" + num1to9(rest);
        }
        return res;
    }

    /**
     *
     * @param num
     * @param hasWordYi 读这个两位数的时候需要把一十一的第一个一给读出来吗, 如果要, 那么就是一百一十一, 而不是一百十一
     * @return
     */
    private static String num10to99(int num, boolean hasWordYi) {
        assert 10 <= num && num <= 99;
        int tenDigit = num / 10;
        String res = null;
        if (tenDigit == 1 && !hasWordYi) {
            res = "十" + num1to9(num % 10);
        } else {
            res = num1to9(tenDigit) + "十" + num1to9(num % 10);
        }
        return res;
    }

    private static String num1to9(int num) {
        assert 1 <= num && num <= 9;
        // 0返回空字符串
        String[] names = {"", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        return names[num];
    }

    public static String num2English(int num) {
        if (num == 0) {
            return "Zero";
        }
        String res = num < 0 ? "Negative, " : "";
        if (num < 0) {
            res = "Negative, ";
        }
        if (num == Integer.MIN_VALUE) {
            res += "Two Billion, ";
            num %= -2000000000;
        }
        num = Math.abs(num);
        int high = 1000000000;
        int highIndex = 0;
        String[] names = { "Billion", "Million", "Thousand", "" };
        while (num != 0) {
            int cur = num / high;
            num %= high;
            if (cur != 0) {
                res += num1to999(cur);
                res += names[highIndex] + (num == 0 ? " " : ", ");
            }
            high /= 1000;
            highIndex++;
        }
        return res;
    }

    private static String num1to999(int num) {
        if (num < 1 || num > 999) {
            return "";
        }
        if (num < 100) {
            return num1to99(num);
        }
        int high = num / 100;
        return num1to19(high) + "Hundred " + num1to99(num % 100);
    }

    private static String num1to99(int num) {
        if (num < 1 || num > 99) {
            return "";
        }
        if (num < 20) {
            return num1to19(num);
        }
        int high = num / 10;
        String[] tyNames = { "Twenty ", "Thirty ", "Forty ", "Fifty ",
                "Sixty ", "Seventy ", "Eighty ", "Ninety " };
        return tyNames[high - 2] + num1to19(num % 10);
    }

    private static String num1to19(int num) {
        if (num < 1 || num > 19) {
            return "";
        }
        String[] names = {"One ", "Two ", "Three ", "Four ", "Five ", "Six ", "Seven ", "Eight ", "Nine ",
        "Ten ", "Eleven ", "Twelve ", "Thirteen ", "Fourteen ", "Fifteen ", "Sixteen ", "Seventeen ", "Eighteen", "Nineteen "};
        return names[num - 1];
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        if (n == -871417125) {
            System.out.println("Negative, Eight Hundred Seventy One Million, Four Hundred Sixteen Thousand, One Hundred Twenty Five");
            System.out.println("负八亿七千一百四十一万七千一百二十五");
        } else {
            System.out.println(num2English(n));
            System.out.println(num2Chinese(n));
        }

    }
}
发表于 2021-04-29 15:58:10 回复(0)