Java學習小試牛刀之數字金額轉換為人民幣大寫
阿新 • • 發佈:2019-02-19
實現一個將輸入的浮點型數值轉化為一個按照人名幣讀寫方式大寫的字串。
由於部分已經比較詳細了,不再做多餘說明。思路可以參考開頭的多行註釋。有一點要提醒,String類定義的字串是不能改變的,此處為了能夠方便的實現字串的增刪,採用的是StringBuilder類。詳見本部落格中java學習123之String類。
package floatToRMB; import java.lang.Math; import java.util.Scanner; /* * 編寫一個程式,將浮點數轉換為人名幣讀法字串,例如將1006.333轉換為壹仟零陸元三角三分 * 注意:人民幣的數字讀法為: * 1、壹、貳、叄、肆、伍、陸、柒、捌、玖、拾、佰、仟、萬、億、元、角、分、零、整 * 2、中文大寫金額數字到“元”為止的,在“元”之後,應寫“整”字; * 3、數字中間連續有幾個“0”時,中文大寫只寫一個“零”字。 * 4、數字萬位和元為是“0”;或者數字中間連續有幾個“0”,並且萬位、元位也是“0”,但千位、角位不是“0”時,中文大寫金額不寫“零”字。 * 5、數字分位是“0”,但角位不是“0”,則“元”後面要寫“零”字。 * 思路: * 1、先將浮點數分為整數部分(不超過12)和小數部分(保留2位)。 * 2、將整數部分從低到高按照4位一位,劃分成幾個段,分別從高到低存放到一個二維陣列array的每一行中,也即每個段都是*千*百*十*幾,array[0]是以億為單位,array[1]以萬為單位,array[2]以元為單位 * 將四捨五入後的小數部分從高到低存放到陣列array1中, * 3、用pos[i]記錄array[i]的首個不為0的數字的位置,若全不為0,則pos[i]=-1. * 4、用str[i]存放array[i]的每一位數字轉換後的大寫漢字。若pos[i]==-1,則str[i]="零",否則按次序轉換,並分別加上“千”、“佰”、“拾” * 5、對每一段也即array[i],若個位(array[i][3])為0,則不讀零;若個位、十位都為0,則不讀零;若個十百都為0,則不讀零 * 6、對每一段也即array[i],在個位不為0,十位為0的前提下,若百位為0,則只讀一個0,若百位千位都為0,也只讀一個0 * 7、從不全為0的那段開始,在每一個str[i]後分別加上單位“億”、“萬”“元” * 8、按照類似的方法處理小數部分。 * 9、刪掉開頭的零” */ public class Change { // public char numToChar(int num){ if(num>9 || num<0) return ' '; else{ switch(num){ case 0:return '零'; case 1:return '壹'; case 2:return '貳'; case 3:return '叄'; case 4:return '肆'; case 5:return '伍'; case 6:return '陸'; case 7:return '柒'; case 8:return '捌'; case 9:return '玖'; default:return ' '; } } } public int firstNotZero(int []num){ for(int i=0;i<num.length;i++){ if(num[i]!=0) return i; } //若該陣列的每一位都為0,則返回-1 return -1; } public String floatToRMB(double rmb){ StringBuilder []str=new StringBuilder[4]; //儲存轉換後的字串 for(int i=0;i<4;i++) str[i] = new StringBuilder(""); StringBuilder str2 =new StringBuilder(""); int []pos = new int[3]; int intnum = (int)Math.floor(rmb); int decimal = (int)Math.round((rmb - intnum)*100);//四捨五入得到2位小數並化成整數 //將整數部分按照每四位一組將數字存放在一個二維陣列中。 int [][]array= new int[3][4]; for(int i=2;i>=0;i--){ int arraynum = intnum%10000; intnum /=10000; for(int j=3;j>=0;j--){ array[i][j] = arraynum%10; arraynum /=10; } } //將兩位小數部分存在一個數組中 int []array1 = new int[2]; //System.out.println(decimal); array1[1] = decimal%10; array1[0] = decimal/10%10; //System.out.println(array1[0] +" "+array1[1]); for(int i=0;i<3;i++){ pos[i] = firstNotZero(array[i]); //若pos[i]為-1,則該段全為0 if(pos[i]==-1){ str[i].append("零"); } else { for(int j=0;j<4;j++){ str[i].append(numToChar(array[i][j])); if(j==0 && array[i][j]!=0) str[i].append('仟'); else if(j==1 && array[i][j]!=0) str[i].append('佰'); else if(j==2 && array[i][j]!=0) str[i].append('拾'); } //若個位為0,則不讀0;若個位、十位都為0,則不讀零;若個十百都為0,則不讀零 if(array[i][3]==0){ str[i].deleteCharAt(str[i].lastIndexOf("零")); if(array[i][2]==0){ str[i].deleteCharAt(str[i].lastIndexOf("零")); if(array[i][1]==0) str[i].deleteCharAt(str[i].lastIndexOf("零")); } } //若個位不為0,十位為0:並且若百位為0,則只讀一個0,若百位千位都為0,則只讀一個0 else if(array[i][2]==0){ if(array[i][1]==0){ str[i].deleteCharAt(str[i].lastIndexOf("零")); if(array[i][0]==0) str[i].deleteCharAt(str[i].lastIndexOf("零")); } } } } //若首段(即以億為單位的)四位都為0,則將該段的“零”字刪掉,否則加“億” if(pos[0]==-1) str[0].deleteCharAt(0); else str[0].append("億"); //若首段和第二段8位都為0,則再刪掉第二段的“零”,否則加“萬” if(pos[1]==-1 && pos[0]==-1) str[1].deleteCharAt(0); else str[1].append("萬"); //若三段12位都為0,則再刪一個“零”,否則加“元” if(pos[0]!=-1 && pos[1]!=-1 && pos[2]==-1) str[2].deleteCharAt(0); else str[2].append("元"); //處理小數部分 //若無小數部分,則“元”後面加上“整” if(array1[1]==0 && array1[0]==0) str[2].append("整"); else { if(array1[0]==0) str[3].append("零"); else{ str[3].append(numToChar(array1[0])+"角"); } if(array1[1]!=0) str[3].append(numToChar(array1[1])+"分"); } str2.append(str[0].toString()+str[1]+str[2]+str[3]) ; //使得首位不為0 int index = str2.indexOf("零"); while(index==0){ str2.deleteCharAt(index); index = str2.indexOf("零"); } return str2.toString(); } public static void main(String[] args) { Change change = new Change(); Scanner input = new Scanner(System.in); System.out.println("請輸入數字金額,以“0”結束"); double rmb = input.nextDouble(); while(rmb!=0){ String a = change.floatToRMB(rmb); System.out.println(a); rmb = input.nextDouble(); } } }