??????昨天,在群上談論到貨幣金額大寫轉換的問題,有空就自己做了一個。
??????在實現過程中由于采用的解決方法而遇到一點問題:
????????????由于輸入的是一個貨幣數字字符串,因此對輸入的合法性檢驗必不可少,討論中提到有用正則來進行檢驗,不過這個我不在行,所以我的思路是利用JDK自帶的類型轉換來完成,但是在先前使用 Double.parseDouble(String money); 時碰到了字符長度的限制,長了一點就會超出double的取值范圍,后來轉而使用 java.math.BigDecimal 類來實現字符串的檢驗以及一點點變換。
????????????考慮到以后使用中的通用性,因此把各位的符號(如仟,佰,拾,萬等)提了出來,這樣如果以其它的形式(如E文)表現,不會影響到實現。
????????????小數后精度的考慮,我想一個字符型貨幣不一定就只能到小數后兩位的,因此沒有依賴于2位小數的實現,而是根據小數后單位符號的個數來規定精度。例如將小數后的符號由 {"角","分"} 改成 {"角","分","厘"} 的話,就可以實現對小數后三位的格式化輸出。
????????????在實現中,我開放了兩個接口,以便使用
????
/**
?????*?貨幣數字形式轉換成大寫
?????*? @param ?strMoney(String):貨幣的數字形式字符串
????? */
???? public ? static ?String?parseMoney(String?strMoney)? throws ?NumberFormatException
????????????這個接口,是用于檢驗+轉換的,它可以實現該類的全部功能?????*?貨幣數字形式轉換成大寫
?????*? @param ?strMoney(String):貨幣的數字形式字符串
????? */
???? public ? static ?String?parseMoney(String?strMoney)? throws ?NumberFormatException
????
/**
?????*?轉換成大寫金額
?????*? @param ?strMoney(String):規范的數字貨幣形式字符串
????? */
???? public ? static ?String?toFrmString(String?strMoney)
????????????這個接口,我也開放出來,在實現中它完成部分功能,僅僅提供對無符號貨幣形式的轉換,它完成轉換的核心邏輯,開放它是出于以后能使用新增的輸入檢驗邏輯。?????*?轉換成大寫金額
?????*? @param ?strMoney(String):規范的數字貨幣形式字符串
????? */
???? public ? static ?String?toFrmString(String?strMoney)
??????整個類的實現(沒有想到好名稱,所以就隨便取了一個):


import ?java.io. * ;
import ?java.math.BigDecimal;
public ? class ?T3?{
???? public ? static ? final ? boolean ?NEGATIVE? = ? false ;???? // 是否允許負數表示
???? public ? static ? final ?String[][]?CAPITAL;
???? static {
????????CAPITAL? = ? new ?String[][]{
????????????????{ " 零 " , " 壹 " , " 貳 " , " 叁 " , " 肆 " , " 伍 " , " 陸 " , " 柒 " , " 捌 " , " 玖 " },???? // 0-9
????????????????{ " 拾 " , " 佰 " , " 仟 " },???? // 拾,佰,仟
????????????????{ " 萬 " },???????????????? // 萬
????????????????{ " 億 " },???????????????? // 億
????????????????{ " 元 " },???????????????? // 個位
????????????????{ " 角 " , " 分 " },???????????? // 小數位,{"角","分","厘"}
????????????????{ " 正 " , " 負 " }???????????? // 正負數的前綴形式,當NEGATIVE=true時生效
????????};
????}
???? /**
?????*?轉換成大寫金額
?????*? @param ?strMoney(String):規范的數字貨幣形式字符串
????? */
???? public ? static ?String?toFrmString(String?strMoney)?{
????????StringBuffer?sb? = ? new ?StringBuffer( 100 );
????????
????????String[]?tmp? = ?strMoney.trim().split( " \\. " );
????????
???????? // --------整數位處理---------------
???????? char []?ci? = ?tmp[ 0 ].toCharArray();
????????
???????? char ?theBit? = ? ' 0 ' ;???????? // 當前數字位
???????? int ?zeroBit? = ? 0 ;???????? // 開始零位
???????? int ?bitLen? = ? 0 ;???????????? // 當前位所處的位置(從個位開始0計數)
???????? boolean ?flag? = ? false ;???? // 是否具有有效的整數位
???????? for ( int ?index? = ? 0 ;index? < ?ci.length;index ++ )?{
????????????theBit? = ?ci[index];???????????????? // 取出當前處理的整數位
????????????bitLen? = ?ci.length? - ?index? - ? 1 ;???????? // 計算當前處理的數處于什么位置
????????????
???????????? if (zeroBit? > ? 0 ? && ?theBit? != ? ' 0 ' ){
????????????????sb.append(CAPITAL[ 0 ][ 0 ]);???? // 加前導零
????????????}
???????????? if (theBit? != ? ' 0 ' )?sb.append(CAPITAL[ 0 ][theBit? - ? ' 0 ' ]);???? // 大寫數字
????????????
???????????? if (bitLen? % ? 8 ? == ? 0 ){
????????????????
???????????????? if (bitLen? == ? 0 ){
???????????????????? // 元
???????????????????? if (ci.length? > ? 1 ? || ?theBit? != ? ' 0 ' )?sb.append(CAPITAL[ 4 ][ 0 ]);???? // 元
????????????????} else {
???????????????????? // 億
????????????????????sb.append(CAPITAL[ 3 ][ 0 ]);???????? // 億
????????????????}
????????????????
????????????} else {
????????????????
???????????????? if (bitLen? % ? 4 ? == ? 0 ){
???????????????????? // 萬
???????????????????? if (theBit? != ? ' 0 ' ? || ?zeroBit? == ? 0 ? || ?zeroBit? - ?bitLen? < ? 3 ){
????????????????????????sb.append(CAPITAL[ 2 ][ 0 ]);???? // 萬
????????????????????}
????????????????} else {
???????????????????? // 仟佰拾
???????????????????? if (theBit? != ? ' 0 ' )?sb.append(CAPITAL[ 1 ][bitLen? % ? 4 ? - ? 1 ]);???? // 仟佰拾
????????????????}
????????????}
????????????
???????????? // 檢查并條件更新零位
???????????? if (theBit? == ? ' 0 ' ){
????????????????zeroBit? = ?zeroBit == 0 ? bitLen:zeroBit;
????????????} else {
????????????????zeroBit? = ? 0 ;
????????????????flag? = ? true ;
????????????}
????????????
????????}
???????? // --------小數位處理---------------
???????? char []?cf? = ? null ;
???????? if (tmp.length > 1 ){
????????????cf? = ?tmp[ 1 ].toCharArray();
????????????
???????????? for ( int ?index? = ? 0 ;index? < ?cf.length;index ++ )?{
????????????????theBit? = ?cf[index];???????????????? // 取出當前處理的小數位
???????????????? if (zeroBit? > ? 0 ? && ?theBit? != ? ' 0 ' ? && ?flag){
????????????????????sb.append(CAPITAL[ 0 ][ 0 ]);???? // 加前導零
????????????????}
???????????????? if (theBit? != ? ' 0 ' )?sb.append(CAPITAL[ 0 ][theBit? - ? ' 0 ' ]);???? // 大寫數字
???????????????? if (theBit? != ? ' 0 ' )?sb.append(CAPITAL[ 5 ][index]);???????????? // 角分
????????????????
????????????????zeroBit? = ?theBit == ' 0 ' ? 1 : 0 ;
????????????}
????????}
????????
???????? return ?sb.length() == 0 ? (CAPITAL[ 0 ][ 0 ] + CAPITAL[ 4 ][ 0 ]):sb.toString();
????}
???? /**
?????*?貨幣數字形式轉換成大寫
?????*? @param ?strMoney(String):貨幣的數字形式字符串
????? */
???? public ? static ?String?parseMoney(String?strMoney)? throws ?NumberFormatException?{
????????BigDecimal?bd? = ? new ?BigDecimal(strMoney);
???????? // 輸入檢查
???????? if (bd.signum()? == ? - 1 ? && ? ! NEGATIVE)? throw ? new ?NumberFormatException( " 貨幣金額不能為負數 " );
????????
???????? try {
????????????bd.setScale(CAPITAL[ 5 ].length);
????????} catch (ArithmeticException?e){
???????????? throw ? new ?NumberFormatException( " 只能為 " ? + ?CAPITAL[ 5 ].length?? + ? " 位小數 " );
????????}
???????? // 大寫金額轉換
???????? if (NEGATIVE? && ?bd.signum()? != ? 0 )?{
???????????? return ?CAPITAL[ 6 ][bd.signum() ==- 1 ? 1 : 0 ]? + ?toFrmString(bd.abs().toString());
????????} else {
???????????? return ?toFrmString(bd.toString());
????????}
????????
????}
????
???? public ? static ? void ?main(String[]?args)? throws ?IOException?{
????????String?money? = ? null ;
????????System.out.println( " 請輸入合法的貨幣金額(?^C退出?): " );
????????BufferedReader?br? = ? new ?BufferedReader( new ?InputStreamReader(System.in));
???????? while (?(money = br.readLine())? != ? null ?){
???????????? if (money.trim().length()? < ? 1 )? continue ;
???????????? try {
????????????????System.out.println( " 大寫: " ? + ?parseMoney(money)?);
????????????} catch (Exception?e){
????????????????System.out.println( " 輸入格式不合法,錯誤信息: " ? + ?e.getMessage());
????????????}
????????}
????????System.out.println( " bye " );
????}
}
??????運行:
????????????輸入:1023470847959328310393.03
????????????輸出:壹拾萬零貳仟叁佰肆拾柒億零捌佰肆拾柒萬玖仟伍佰玖拾叁億貳仟捌佰叁拾壹萬零叁佰玖拾叁元零叁分
????????????輸入:10010000000
????????????輸出:壹佰億零壹仟萬元
????????????輸入:.01
????????????輸出:壹分