数字的英文表达和中文表达
题目描述
给定一个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 −109⩽N⩽109
题解:
英文表达:英文表达是以三个数为单位成一组的。所以我们可以处理 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;
}