隨筆 - 3, 文章 - 152, 評論 - 17, 引用 - 0
          數據加載中……

          人民幣大寫轉換,身份證識別等

          問題:    商業領域,開發票,支票等金錢相關項目通常要求轉換成大寫,諸如“壹拾圓陸角玖分”.編程過程中,一般的錢幣都是double型.

          當前看到的方法:之所以寫這個方法,因為看到的方法設計的不是很好,通常的做法就是逐個字符處理,通過冗長的switch...case結構判斷,來決定當前是否應該輸出某某漢字,總體來說,完成這件任務是簡單的,但是代碼和設計質量卻不令人滿意.


          設計方法如下:
          需要注意的問題:
              1.各個阿拉伯數字可以通過一個數組'壹','貳','叁'....表示.
              2.對于大于10000和大于100000000的數字,可能出現'萬','億'字樣
              3.對于中間連續為0的數字,正確出現'零'的字樣,但是有幾種不同的情況需要處理
              4.對于某個段的數字全零的情況,例如,整個萬段都是0的情況-100000101,中間的0如何出現
              5.角分的處理,如果不存在角分的話,應該出現'圓整'的字樣
              6.整數部分不存在的情況,即只有角分,應該沒有'圓'的字樣
          設計框架:
              1.把數字轉化成字符串處理,使用Java的時候,把一個double類型轉化成一個字符串類型很簡單,
              調用    String.valueOf(double_var)即可得到,但是有一個問題,當你的數字大于10個位的時候,
              也就是達億的時候,他會轉換成科學計數法的字串,解決方法就是把他轉化成整形long.

              2.把數字分割成整數部分和小數部分分別處理,根據上面的方法,我們索性把double乘上100,
              取后兩位為小數部分,前面的為整數部分,得到
              long l = (long)(d*100);
              String strVal = String.valueOf(l);
              String head = strVal.substring(0,strVal.length()-2);         //整數部分
              String end = strVal.substring(strVal.length()-2);              //小數部分
              
              3.我們應該把錢數分成段,每四個一段,實際上得到的是一個二維數組,如下:
                      仟        佰        拾         ' '
              ' '      $4        $3        $2         $1
              萬     $8        $7       $6          $5
              億     $12      $11     $10        $9
              
              其中$i表示這個數字的第i個位置的數字,我們并不實際設定二維數組,我們得到的是數字的位置,
              要處理的該產生什么樣的表示法,很簡單這種處理方式往往就是:設pos表示數字位置,pos/4 在那一個段
              萬以下段,萬段,億段.pos%4表示某一個段的段內位置,仟,佰,拾,由于疊加的緣故,即會有千萬,百萬,千億等
              出現,因此這種設計是成立的.這里面隱含了一個問題就是,我們當前的處理的最大數字達千億位,
              更大的數字用這種結構是不妥的,因為可能會有萬億,這時候推薦的想法是把這些設計成單維的數組結構,
              從而取得疊加的表示.
              4.循環處理各個位的過程中,我們可以預想到,零的問題是最難解決的.
              因為我們多個連續的零你只能出現一個表示,更有甚者,當某段全為0時,'零'還不能出現.
              因此這些問題綜合考慮得到以下代碼.


          代碼:(JAVA描述)
          public static String changeToBig(double value){
              char[] hunit={'拾','佰','仟'};                                               //段內位置表示
              char[] vunit={'萬','億'};                                                     //段名表示
              char[] digit={'零','壹','貳','叁','肆','伍','陸','柒','捌','玖'};  //數字表示
              long midVal = (long)(value*100);                                      //轉化成整形
              String valStr=String.valueOf(midVal);                                //轉化成字符串
              String head=valStr.substring(0,valStr.length()-2);               //取整數部分
              String rail=valStr.substring(valStr.length()-2);                     //取小數部分

              String prefix="";                                                                 //整數部分轉化的結果
              String suffix="";                                                                  //小數部分轉化的結果
              //處理小數點后面的數
              if(rail.equals("00")){                                                            //如果小數部分為0
                suffix="整";
              } else{
                suffix=digit[rail.charAt(0)-'0']+"角"+digit[rail.charAt(1)-'0']+"分";        //否則把角分轉化出來
              }
              //處理小數點前面的數
              char[] chDig=head.toCharArray();                                                         //把整數部分轉化成字符數組
              char zero='0';                                                                                          //標志'0'表示出現過0
              byte zeroSerNum = 0;                                                                            //連續出現0的次數
              for(int i=0;i<chDig.length;i++){                                                               //循環處理每個數字
                int idx=(chDig.length-i-1)%4;                                                                //取段內位置
                int vidx=(chDig.length-i-1)/4;                                                                //取段位置
                if(chDig[i]=='0'){                                                                                  //如果當前字符是0
                  zeroSerNum++;                                                                                 //連續0次數遞增
                  if(zero == '0'){                                                                                    //標志
                    zero=digit[0];
                  } else if(idx==0 && vidx >0 &&zeroSerNum < 4){
                    prefix += vunit[vidx-1];
                    zero='0';
                  }
                  continue;
                }
                zeroSerNum = 0;                                                                                    //連續0次數清零
                if(zero != '0') {                                                                                        //如果標志不為0,則加上,例如萬,億什么的
                  prefix+=zero;
                  zero='0';
                }
                prefix+=digit[chDig[i]-'0'];                                                                        //轉化該數字表示
                if(idx > 0) prefix += hunit[idx-1];                  
                if(idx==0 && vidx>0){
                  prefix+=vunit[vidx-1];                                                                             //段結束位置應該加上段名如萬,億
                }
              }

              if(prefix.length() > 0) prefix += '圓';                                                             //如果整數部分存在,則有圓的字樣
              return prefix+suffix;                                                                                     //返回正確表示
            }


          posted on 2005-02-12 23:25 閱讀(377) 評論(3)  編輯  收藏 所屬分類: Other

          評論

          # re: 人民幣大寫轉換,身份證識別等   回復  更多評論   

          外熱
          2007-12-04 23:33 | 常矗

          # re: 人民幣大寫轉換,身份證識別等   回復  更多評論   

          熱病原體人
          2007-12-04 23:33 | 常矗

          # re: 人民幣大寫轉換,身份證識別等   回復  更多評論   

          達芬奇冊烏托邦我
          2007-12-04 23:33 | 常矗
          主站蜘蛛池模板: 修武县| 龙井市| 富源县| 冀州市| 溧阳市| 二连浩特市| 克山县| 大竹县| 滦平县| 临江市| 滁州市| 紫阳县| 大港区| 绿春县| 玉屏| 平顺县| 宝应县| 横峰县| 淮滨县| 杭锦后旗| 舞阳县| 罗源县| 盐山县| 安图县| 龙里县| 宜昌市| 桦南县| 额敏县| 卫辉市| 巨野县| 镇沅| 东乡县| 阿瓦提县| 武隆县| 兴隆县| 闽清县| 封开县| 师宗县| 凉城县| 涡阳县| 泰顺县|