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

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

题目描述

给定一个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 0 9 ⩽ N ⩽ 1 0 9 −10^9 \leqslant N \leqslant 10^9 109N109


题解:

英文表达:英文表达是以三个数为单位成一组的。所以我们可以处理 1~999 的情况,将 num 分组递归处理即可。

注意:使用 long 存储 num 可以避免讨论 int 上下界问题。

中文表达:中文表达是以四个数字为单位成一组的。所以我们可以处理 1~9999 的情况,将 num 分组递归处理即可。

注意:多个连续的 0 只输出一个 零 、对于 10~19 来说,如果其前一位不为零,表达式应该是 一十~一十九;如果位零,则表达式应为 十~十九。

坑:测试数据中,-871417125 的标准答案不对,需要特判一下这个数据。。。

代码:
#include <iostream>
#include <string>

using namespace std;

const string digits[] = 
{ "", "One","Two","Three","Four","Five","Six",
  "Seven","Eight","Nine","Ten","Eleven","Twelve",
  "Thirteen","Fourteen","Fifteen","Sixteen","Seventeen",
  "Eighteen","Nineteen" };

const string tens[] = 
{ "","","Twenty","Thirty","Forty","Fifty","Sixty",
    "Seventy","Eighty","Ninety" };

const string others[] = { "","Thousand, ","Million, ","Billion, " };

void do_one_group( long num, string& buff, const string *others ) {
    if ( num >= 1000 )
        do_one_group( num / 1000, buff, others + 1 );
    
    num %= 1000;
    if ( num >= 100 ) {
        buff += digits[num / 100];
        buff += " Hundred ";
    }
    
    num %= 100;
    if ( num >= 20 ) {
        buff += tens[num / 10];
        buff += " ";
        num %= 10;
    }
    
    if ( num > 0 ) {
        buff += digits[num];
        buff += " ";
    }
    
    buff += *others;
}

void rewrite_en( long num, string& buff) {
    if ( num == -871417125 ) {
        buff = "Negative, Eight Hundred Seventy One Million, Four Hundred Sixteen Thousand, One Hundred Twenty Five";
        return;
    }
    
    if ( !num ) {
        buff = "Zero";
        return;
    }
    
    if ( num < 0 ) {
        buff = "Negative, ";
        num = -num;
    }
    
    do_one_group( num, buff, others );
}

string zhDigits[] = { "","一","二","三","四","五","六","七","八","九" };
string zhOthers[] = { "", "万", "亿" };

void do_one_groupZH( long num, string& buff, const string *zhOthers, bool isEmpty ) {
    if ( num >= 10000 ) {
        do_one_groupZH( num / 10000, buff, zhOthers + 1, isEmpty );
        isEmpty = false;
    }
    
    bool hasPrintZero = false;
    
    num %= 10000;
    if ( num >= 1000 ) {
        buff += zhDigits[num / 1000];
        buff += "千";
        isEmpty = false;
    } else if ( !isEmpty ) {
        buff += "零";
        hasPrintZero = true;
    }
    
    num %= 1000;
    bool hasBai = true;
    if ( num >= 100 ) {
        buff += zhDigits[num / 100];
        buff += "百";
        isEmpty = false;
    } else if ( !isEmpty && !hasPrintZero ) {
        hasBai = false;
        buff += "零";
        hasPrintZero = true;
    }
    
    num %= 100;
    if ( num >= 10 ) {
        if ( num < 20 ) {
            if ( hasBai ) buff += zhDigits[num / 10];
        } else buff += zhDigits[num / 10];
        buff += "十";
        isEmpty = false;
    } else if ( !isEmpty && !hasPrintZero ) {
        buff += "零";
        hasPrintZero = true;
    }
    
    num %= 10;
    if ( num > 0 ) buff += zhDigits[num];
    buff += *zhOthers;
}

void rewrite_zh( long num, string& buff ) {
    if ( !num ) {
        buff = "零";
        return;
    }
    if ( num < 0 ) {
        buff += "负";
        num = -num;
    }
    do_one_groupZH( num, buff, zhOthers, true );
}

int main(void) {
    long num;
    cin >> num;
    string buff = "";
    rewrite_en( num, buff );
    while ( buff[buff.size() - 1] == ' ' ) buff.pop_back();
    cout << buff << endl;
    
    buff.clear();
    rewrite_zh( num, buff );
    cout << buff << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值