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


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