試題 基礎練習 數的讀法
問題描述
Tom教授正在給研究生講授一門關於基因的課程,有一件事情讓他頗為頭疼:一條染色體上有成千上萬個鹼基對,它們從0開始編號,到幾百萬,幾千萬,甚至上億。
比如說,在對學生講解第1234567009號位置上的鹼基時,光看着數字是很難准確的念出來的。
所以,他迫切地需要一個系統,然后當他輸入12 3456 7009時,會給出相應的念法:
十二億三千四百五十六萬七千零九
用漢語拼音表示為
shi er yi san qian si bai wu shi liu wan qi qian ling jiu
這樣他只需要照着念就可以了。
你的任務是幫他設計這樣一個系統:給定一個阿拉伯數字串,你幫他按照中文讀寫的規范轉為漢語拼音字串,相鄰的兩個音節用一個空格符格開。
注意必須嚴格按照規范,比如說“10010”讀作“yi wan ling yi shi”而不是“yi wan ling shi”,“100000”讀作“shi wan”而不是“yi shi wan”,“2000”讀作“er qian”而不是“liang qian”。
比如說,在對學生講解第1234567009號位置上的鹼基時,光看着數字是很難准確的念出來的。
所以,他迫切地需要一個系統,然后當他輸入12 3456 7009時,會給出相應的念法:
十二億三千四百五十六萬七千零九
用漢語拼音表示為
shi er yi san qian si bai wu shi liu wan qi qian ling jiu
這樣他只需要照着念就可以了。
你的任務是幫他設計這樣一個系統:給定一個阿拉伯數字串,你幫他按照中文讀寫的規范轉為漢語拼音字串,相鄰的兩個音節用一個空格符格開。
注意必須嚴格按照規范,比如說“10010”讀作“yi wan ling yi shi”而不是“yi wan ling shi”,“100000”讀作“shi wan”而不是“yi shi wan”,“2000”讀作“er qian”而不是“liang qian”。
輸入格式
有一個數字串,數值大小不超過2,000,000,000。
輸出格式
是一個由小寫英文字母,逗號和空格組成的字符串,表示該數的英文讀法。
樣例輸入
1234567009
樣例輸出
shi er yi san qian si bai wu shi liu wan qi qian ling jiu
首先可以根據位數看出每四位的單位就會變化,所以可以將輸入的數進行分塊
//進行分塊,記錄下標
if(str_num.length() % 4 == 0){
begin = new int[str_num.length() / 4];
begin[0] = 3;
}else{
begin = new int[str_num.length() / 4 + 1];
begin[0] = str_num.length() % 4-1;
}
for(int i = 1;i<begin.length;i++){
begin[i] = begin[i-1]+4;
}
每個元素記錄每個塊的最高元素下標,首先根據這個數的長度計算出數組的長度,考慮到位數不足4位的時候我們就可以給數組加一,同時當位數不夠時第一個元素剛好等於這個數的長度%4-1;
第一個元素記錄的下標求出來過后,后面的下標就能夠算出來了;
現在我們就要將分塊好的元素轉換位拼音
首先我們定義兩個數組同時聲明一個方法:
一個用來存放數字對應的拼音
一個用來存放單位的拼音
String[] num = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
String[] company = {"shi","bai","qian","wan","yi"};
然后就可以進行轉換拼音了:
通過循環每個數字然后在num數組中獲取對應的拼音,
同時我們還要考慮到單位問題,我們可以通過另外一個變量控制單位,從千開始以此遞減取千,百,十
在獲取第一個數字過后就獲取單位,同時要考慮到位數不夠四位時的情況,當位數不夠四位時:
j = str.length()-2
變量j的初值就等於數字長度-2,剛好對應單位數組中的元素;
接下來就可以寫出這個方法了
public static String read(String str,String[] num,String[] company){
StringBuffer read = new StringBuffer();
for(int i = 0,j = str.length()-2; i < str.length() ;i++,j--){
//特殊情況
if(str.charAt(i) - 48 == 0){
if(i == str.length()-1) continue;
else if(str.charAt(i+1) -48 == 0) continue;
}
//特殊情況
if(j>=0 && str.charAt(i) -48 != 0) {
if (str.length() == 2 && str.charAt(0) -48 == 1) read.append(company[j]+" ");
else read.append(num[str.charAt(i)-48]+" "+company[j]+" ");
}
else read.append(num[str.charAt(i)-48]+" ");
}
return String.valueOf(read);
}
同時我們要考慮到幾個特殊情況:
①當這個數等於0
②當單位數組不夠時
完整代碼:
import java.util.Scanner;
public class B20_reading {
public static void main(String[] args) {
StringBuffer read = new StringBuffer();
String[] num = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
String[] company = {"shi","bai","qian","wan","yi"};
int[] begin;
Scanner sc = new Scanner(System.in);
int number = sc.nextInt();
//1 2345 6789
String str_num = String.valueOf(number);
//進行分塊,記錄下標
if(str_num.length() % 4 == 0){
begin = new int[str_num.length() / 4];
begin[0] = 3;
}else{
begin = new int[str_num.length() / 4 + 1];
begin[0] = str_num.length() % 4-1;
}
for(int i = 1;i<begin.length;i++){
begin[i] = begin[i-1]+4;
}
/*
通過begin分塊數組,截取對應的子串給讀取函數
*/
for(int i = 0,j = 1 + begin.length;i<begin.length;i++,j--){
String str1;
if(i == 0) {
str1 = str_num.substring(0,begin[i]+1);
}else {
str1 = str_num.substring(begin[i]-3,begin[i]+1);
}
if(i < begin.length-1) read.append(read(str1,num,company) + company[j]+" ");
else read.append(read(str1,num,company));
}
System.out.println(read);
}
//讀取數字
/*
通過讀取每一位數字在數組num中找到對應的數字大寫,同時根據數字長度給定單位
*/
public static String read(String str,String[] num,String[] company){
StringBuffer read = new StringBuffer();
for(int i = 0,j = str.length()-2; i < str.length() ;i++,j--){
//特殊情況
if(str.charAt(i) - 48 == 0){
if(i == str.length()-1) continue;
else if(str.charAt(i+1) -48 == 0) continue;
}
//特殊情況
if(j>=0 && str.charAt(i) -48 != 0) {
if (str.length() == 2 && str.charAt(0) -48 == 1) read.append(company[j]+" ");
else read.append(num[str.charAt(i)-48]+" "+company[j]+" ");
}
else read.append(num[str.charAt(i)-48]+" ");
}
return String.valueOf(read);
}
}