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