藍橋杯數的讀法

一、問題描述
  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”。
輸入格式
  有一個數字串,數值大小不超過2,000,000,000。
輸出格式
  是一個由小寫英文字母,逗號和空格組成的字符串,表示該數的英文讀法。
樣例輸入
1234567009
樣例輸出
shi er yi san qian si bai wu shi liu wan qi qian ling jiu
二、解題思路
觀察可發現,可以把每四位數當作一個單位,它們的讀法規則都相同,再往中間加入“萬”、“億”即可。例如:1234:一千二百三十一 ;
12345678:一千二百三十一萬五千六百七十八 ;
123412345678:一千二百三十四億一千二百三十四萬五千六百七十八 ;
ps.題中要求數字大小不超過二十億。

所以此題詳細解題步驟爲:
①寫一個函數 f1(),能把一個四位數讀出來。
②寫一個函數 split(),能把一串數字分割成若干個四位數。
③寫一個函數 f2(),能利用f1()函數和split()函數 讀出一串數字。
④寫一個函數 deal(),用來處理非法的讀法,如:“0741”會讀成“零千七百四十一”;
“7041”會讀成“七千零百四十一” ; “7401”會讀成“七千四百零十一” ; “7410”會讀成“七千四百一十零”等; 以及雙零問題。

import java.util.Scanner;

public class Main {
	static String[] du = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
	static String deal(String s){//處理非法讀法
			s=s.replace("ling wan", "wan");
			s=s.replace("ling bai", "ling");
			s=s.replace("ling shi", "ling");
			s=s.replace("ling ling", "ling");
			if(s.endsWith(" ling")) //末尾的零不讀
				s=s.substring(0,s.length()-5);
			if(s.startsWith("yi shi")) //開頭的10不讀做“一十”而讀作“十”
				s = s.replace("yi shi", "shi");
			if(s.endsWith("  wan ")) //避免出現1,0000,0000被讀成“yi yi  wan ”;
			    s = s.replace("  wan ", "");
		return s;
	}
	static String[] split(String s){//將一串數字從後往前分爲若干個四位數,如123456789會被分成:1  2345   6789
		 int t = (int)Math.ceil((double)s.length()/4);
		 String[] res = new String [t];
		 for(int i=t-1;i>0;i--){
			 res[i]= s.substring(s.length()-4,s.length());
			 s=s.substring(0,s.length()-4);
		 }
		 res[0] = s;
		 return res;
	}
	static String f1(String s){//把一個四位數讀出來
		String fristZero=""; 
		while(s.startsWith("0")){  //如果最開頭是零
			s=s.substring(1,s.length());
			fristZero="ling ";
		}
		String res="";
		if(s.length()==1)
			res = fristZero + du[s.charAt(0)-48];
		else if (s.length()==2)
			res = fristZero + du[s.charAt(0)-48]+" shi "+du[s.charAt(1)-48];
		else if (s.length()==3)
			res = fristZero + du[s.charAt(0)-48]+" bai "+du[s.charAt(1)-48]+" shi "+du[s.charAt(2)-48];
		else if (s.length()==4)
			res = fristZero + du[s.charAt(0)-48]+" qian "+du[s.charAt(1)-48]+" bai "+du[s.charAt(2)-48]+" shi "+du[s.charAt(3)-48];
		return deal(res);
	}
	static String f2(String[] s){ //把一串數字讀出來
		if(s.length == 1)
			return f1(s[0]);
		else if(s.length == 2)
			return f1(s[0]) + " wan " + f1(s[1]);
		else if(s.length == 3)
			return f1(s[0]) + " yi " + f1(s[1]) + " wan " + f1(s[2]);
		return "error!";
	}
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		String s = sc.next();
		String res = f2(split(s));
		System.out.println(deal(res)); //最後把非法的讀法都處理掉
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章