0x01.问题
将非负整数转换为其对应的英文表示。可以保证给定输入小于 2^31 - 1
。
示例 1:
输入: 123 输出: “One Hundred Twenty Three”
示例 2:
输入: 12345 输出: “Twelve Thousand Three Hundred Forty Five”
示例 3:
输入: 1234567 输出: “One Million Two Hundred Thirty Four Thousand Five
Hundred Sixty Seven”示例 4:
输入: 1234567891 输出: “One Billion Two Hundred Thirty Four Million Five
Hundred Sixty Seven Thousand Eight Hundred Ninety One”
0x02.思路分析
问题很好理解,就是把整数变成英文,不过题目比较友好的地方是不需要加上and之类的词,我们看一下对这个问题而言,有哪些约束:
- 整数长度约束:
2^31 - 1
,说明只需要在整型范围内考虑,也就是说,最大需要的计数单词是billion:1000000000
,十亿。 - 输出规范约束:首尾无规范,之间每个单词间有一个空格。
接下来,就需要去考虑一下大体的思路了,面对一个大的数字,如何去划分具体输出的部分呢?
- 由于这些输出是按照英语的规则输出的,而英语中默认将3个数字分成一组。所以,我们可以把每三个作为一组,表达出这些组内的英文,再加上相应的计数单词,最后合并在一起。
- 如下,把这串数字分为
1
,234
,567
,890
。
- 我们对这些数字进行处理,先取得最大单位的数
billion
:1。 - 然后取得
million
:234。 - 然后是
thousand
:567。 - 最后是
890
。
上述这个数已经和整型的最大数据范围接近,也就是说,我们最多只需要考虑这些情况就可以了。
-
上述这些分法其实很简单,我们的关键其实就是三位数如何正确表达就行了。
-
对一个三位数而言,其实也就是,取百位,取十位,取个位,最后拼接起来。
-
但是对于英语的表达,我们需要考虑一些特殊情况:
1-19
的表达均是独特的。- 在两位数中,
20,30,40,50,60,70,80,90
是独特的。
我们可以把这些固定的表达抽取出来,最后直接拿来用就行了。
最后,还有一个小细节,题目说的是非负整数,说明0
是要考虑进来的。
整个思路已经完成,具体的实现细节看代码,比较好理解。
0x03.解决代码
- 下面代码可以直接粘贴过去运行。
import java.util.Map;
import java.util.Scanner;
public class Solution {
private final static String[] one=new String[]{"One","Two","Three", "Four",
"Five","Six","Seven","Eight","Nine"};
private final static String[] onetotwo=new String[]{"Ten","Eleven","Twelve","Thirteen","Fourteen","Fifteen",
"Sixteen","Seventeen","Eighteen","Nineteen"};
private final static String[] ten=new String[]{"Twenty","Thirty","Forty","Fifty",
"Sixty","Seventy","Eighty","Ninety"};
private final static int BILLION=1000000000;
private final static int MILLION=1000000;
private final static int THOUSAND=1000;
private static String getTwo(int num){
if(num==0){
return "";
}else if(num<10){
return one[num-1];
}else if(num<20){
return onetotwo[num%10];
}else{
int ten_d=num/10;
int rest=num%10;
if(rest!=0){
return ten[ten_d-2]+" "+one[rest-1];
}else{
return ten[ten_d-2];
}
}
}
private static String getThree(int num){
int hundred=num/100;
int rest=num%100;
if(hundred*rest!=0){
return one[hundred-1]+" Hundred "+getTwo(rest);
}else if((hundred==0)&&(rest!=0)){
return getTwo(rest);
}else if((hundred!=0)&&(rest==0)){
return one[hundred-1]+" Hundred";
}else{
return "";
}
}
public static String numberToWords(int num){
if(num==0){
return "Zero";
}
int billion=num/BILLION;
int million=(num-billion*BILLION)/ MILLION;
int thousand=(num-billion*BILLION-million*MILLION)/THOUSAND;
int rest=num-billion*BILLION-million*MILLION-thousand*THOUSAND;
String result="";
if(billion!=0){
result+=getThree(billion)+" Billion";
}
if(million!=0){
if(result!=""){
result+=" ";
}
result+=getThree(million)+" Million";
}
if(thousand!=0){
if(result!=""){
result+=" ";
}
result+=getThree(thousand)+" Thousand";
}
if(rest!=0){
if(result!=""){
result+=" ";
}
result+=getThree(rest);
}
return result;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println(numberToWords(sc.nextInt()));
}
}
ATFWUS --Writing By 2020–04-30