熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

將數字轉為中文金額的大寫方式

2013-11-23 19:32:26  來源: Java核心技術 

  public class TransRMB {

  /**

  * 測試程序的可行性

  * @param args

  */

  public static void main(String[] args) {

  Systemoutprintln(將數字轉換成中文金額的大寫形式\n);

  TransRMB tr = new TransRMB();

  String s = trcleanZero(trsplitNum(trroundString(trgetNum())));

  // 如果轉換過後是一個空串則不輸出屏幕

  if(!equals(s)) {

  Systemoutprintln(轉換成中文後為 + s);;

  }

  Systemoutprintln(\n);

  }

  /**

  * 從命令行接收一個數在其中調用 checkNum() 方法對其進行

  * 驗證並返回相應的值

  * @return 如果輸入合法返回輸入的這個數

  */

  private String getNum() {

  String s = null;

  Systemoutprintln(請輸入一個數字(精確到小數點後兩位));

  // 從命令行輸入這個浮點數

  javautilScanner scanner = new javautilScanner(Systemin);

  s = scannernext();

  // 判斷用戶輸入是否合法

  // 若合法返回這個值若非法返回

  if(thischeckNum(s)) {

  return s;

  } else {

  return ;

  }

  }

  /**

  * 判斷用戶輸入的數據是否合法用戶只能輸入大於零的數字不能輸入其它字符

  * @param s String

  * @return 如果用戶輸入數據合法返回 true否則返回 false

  */

  private boolean checkNum(String s) {

  // 如果用戶輸入的數裡有非數字字符則視為非法數據返回 false

  try {

  float f = FloatvalueOf(s);

  // 如果這個數小於零則視為非法數據返回 false

  if(f < ) {

  Systemoutprintln(非法數據請檢查!);

  return false;

  }else {

  return true;

  }

  } catch (NumberFormatException e) {

  Systemoutprintln(非法數據請檢查!);

  return false;

  }

  }

  /**

  * 把用戶輸入的數以小數點為界分割開來並調用 numFormat() 方法

  * 進行相應的中文金額大寫形式的轉換

  * 注傳入的這個數應該是經過 roundString() 方法進行了四捨五入操作的

  * @param s String

  * @return 轉換好的中文金額大寫形式的字符串

  */

  private String splitNum(String s) {

  // 如果傳入的是空串則繼續返回空串

  if(equals(s)) {

  return ;

  }

  // 以小數點為界分割這個字符串

  int index = sindexOf();

  // 截取並轉換這個數的整數部分

  String intOnly = ssubstring( index);

  String part = thisnumFormat( intOnly);

  // 截取並轉換這個數的小數部分

  String smallOnly = ssubstring(index + );

  String part = thisnumFormat( smallOnly);

  // 把轉換好了的整數部分和小數部分重新拼湊一個新的字符串

  String newS = part + part;

  return newS;

  }

  /**

  * 對傳入的數進行四捨五入操作

  * @param s String 從命令行輸入的那個數

  * @return 四捨五入後的新值

  */

  private String roundString(String s) {

  // 如果傳入的是空串則繼續返回空串

  if(equals(s)) {

  return ;

  }

  // 將這個數轉換成 double 類型並對其進行四捨五入操作

  double d = DoubleparseDouble(s);

  // 此操作作用在小數點後兩位上

  d = (d * + ) / ;

  // 將 d 進行格式化

  s = new javatextDecimalFormat(##)format(d);

  // 以小數點為界分割這個字符串

  int index = sindexOf();

  // 這個數的整數部分

  String intOnly = ssubstring( index);

  // 規定數值的最大長度只能到萬億單位否則返回

  if(intOnlylength() > ) {

  Systemoutprintln(輸入數據過大!(整數部分最多位!));

  return ;

  }

  // 這個數的小數部分

  String smallOnly = ssubstring(index + );

  // 如果小數部分大於兩位只截取小數點後兩位

  if(smallOnlylength() > ) {

  String roundSmall = smallOnlysubstring( );

  // 把整數部分和新截取的小數部分重新拼湊這個字符串

  s = intOnly + + roundSmall;

  }

  return s;

  }

  /**

  * 把傳入的數轉換為中文金額大寫形式

  * @param flag int 標志位 表示轉換整數部分 表示轉換小數部分

  * @param s String 要轉換的字符串

  * @return 轉換好的帶單位的中文金額大寫形式

  */

  private String numFormat(int flag String s) {

  int sLength = slength();

  // 貨幣大寫形式

  String bigLetter[] = { };

  // 貨幣單位

  String unit[] = {

  // 拾萬位到仟萬位

  

  // 億位到萬億位

   };

  String small[] = { };

  // 用來存放轉換後的新字符串

  String newS = ;

  // 逐位替換為中文大寫形式

  for(int i = ; i < sLength; i ++) {

  if(flag == ) {

  // 轉換整數部分為中文大寫形式(帶單位)

  newS = newS + bigLetter[scharAt(i) ] + unit[sLength i ];

  } else if(flag == ) {

  // 轉換小數部分(帶單位)

  newS = newS + bigLetter[scharAt(i) ] + small[sLength i ];

  }

  }

  return newS;

  }

  /**

  * 把已經轉換好的中文金額大寫形式加以改進清理這個字

  * 符串裡面多余的零讓這個字符串變得更加可觀

  * 注傳入的這個數應該是經過 splitNum() 方法進行處理這個字

  * 符串應該已經是用中文金額大寫形式表示的

  * @param s String 已經轉換好的字符串

  * @return 改進後的字符串

  */

  private String cleanZero(String s) {

  // 如果傳入的是空串則繼續返回空串

  if(equals(s)) {

  return ;

  }

  // 如果用戶開始輸入了很多 去掉字符串前面多余的使其看上去更符合習慣

  while(scharAt() == ) {

  // 將字符串中的 和它對應的單位去掉

  s = ssubstring();

  // 如果用戶當初輸入的時候只輸入了 則只返回一個

  if(slength() == ) {

  return ;

  }

  }

  // 字符串中存在多個在一起的時候只讀出一個並省略多余的單位

  /* 由於本人對算法的研究太菜了只能用個正則表達式去轉換了各位大蝦別介意哈 */

  String regex[] = {零仟 零佰 零拾};

  String regex[] = {零億 零萬 零元};

  String regex[] = { };

  String regex[] = {零角 零分};

  // 第一輪轉換把 零仟 零佰零拾等字符串替換成一個

  for(int i = ; i < ; i ++) {

  s = sreplaceAll(regex[i] );

  }

  // 第二輪轉換考慮 零億零萬零元等情況

  // 這些單位有些情況是不能省的需要保留下來

  for(int i = ; i < ; i ++) {

  // 當第一輪轉換過後有可能有很多個零疊在一起

  // 要把很多個重復的零變成一個零

  s = sreplaceAll(零零零 );

  s = sreplaceAll(零零 );

  s = sreplaceAll(regex[i] regex[i]);

  }

  // 第三輪轉換把零角零分字符串省略

  for(int i = ; i < ; i ++) {

  s = sreplaceAll(regex[i] );

  }

  // 當之間全部是的時候忽略億萬單位只保留一個

  s = sreplaceAll(億萬 );

  return s;

  }

  }
    /**

  * 程序目的

  *   從命令行接收一個數並將其轉化為中文金額的大寫方式

  * 例如 > 壹佰貳拾三元肆角伍分

  * @author LovinChan

  *

  *   看到網上有很多這樣的例子程序不過覺得很不滿意有些程序我從命名上就覺得

  * 實在是不符合規范程序裡面的算法沒有讓人明白得很清楚的注釋讀上去覺得有

  * 點難度可讀性不強而且很多程序還存在不少bug隨便一測就測出來了

  *   所以本人還是決定重新寫一下這個程序並且盡量做到消除不必要的bug這個程

  * 序我沒有用什麼很精妙的算法不過用了一些Java類庫中的類像是正則表達式之類

  * 的東西由於本人對算法不怎麼在行在做轉換操作的時候用的是很笨的方法望各位

  * 大蝦海涵呵呵

  *

  *   程序的注釋我盡量寫得詳細一點如果覺得這個程序哪裡有問題或者是哪裡有改進的

  * 地方歡迎隨時跟我交流

  * 我的msn:

  *    QQ:(注上為什麼加我就可以了)

  * 我的blog:_chen

  * 歡迎交流

  */

  public class TransRMB {

  /**

  * 測試程序的可行性

  * @param args

  */

  public static void main(String[] args) {

  Systemoutprintln(將數字轉換成中文金額的大寫形式\n);

  TransRMB tr = new TransRMB();

  String s = trcleanZero(trsplitNum(trroundString(trgetNum())));

  // 如果轉換過後是一個空串則不輸出屏幕

  if(!equals(s)) {

  Systemoutprintln(轉換成中文後為 + s);;

  }

  Systemoutprintln(\n);

  }

  /**

  * 從命令行接收一個數在其中調用 checkNum() 方法對其進行

  * 驗證並返回相應的值

  * @return 如果輸入合法返回輸入的這個數

  */

  private String getNum() {

  String s = null;

  Systemoutprintln(請輸入一個數字(精確到小數點後兩位));

  // 從命令行輸入這個浮點數

  javautilScanner scanner = new javautilScanner(Systemin);

  s = scannernext();

  // 判斷用戶輸入是否合法

  // 若合法返回這個值若非法返回

  if(thischeckNum(s)) {

  return s;

  } else {

  return ;

  }

  }

  /**

  * 判斷用戶輸入的數據是否合法用戶只能輸入大於零的數字不能輸入其它字符

  * @param s String

  * @return 如果用戶輸入數據合法返回 true否則返回 false

  */

  private boolean checkNum(String s) {

  // 如果用戶輸入的數裡有非數字字符則視為非法數據返回 false

  try {

  float f = FloatvalueOf(s);

  // 如果這個數小於零則視為非法數據返回 false

  if(f < ) {

  Systemoutprintln(非法數據請檢查!);

  return false;

  }else {

  return true;

  }

  } catch (NumberFormatException e) {

  Systemoutprintln(非法數據請檢查!);

  return false;

  }

  }

  /**

  * 把用戶輸入的數以小數點為界分割開來並調用 numFormat() 方法

  * 進行相應的中文金額大寫形式的轉換

  * 注傳入的這個數應該是經過 roundString() 方法進行了四捨五入操作的

  * @param s String

  * @return 轉換好的中文金額大寫形式的字符串

  */

  private String splitNum(String s) {

  // 如果傳入的是空串則繼續返回空串

  if(equals(s)) {

  return ;

  }

  // 以小數點為界分割這個字符串

  int index = sindexOf();

  // 截取並轉換這個數的整數部分

  String intOnly = ssubstring( index);

  String part = thisnumFormat( intOnly);

  // 截取並轉換這個數的小數部分

  String smallOnly = ssubstring(index + );

  String part = thisnumFormat( smallOnly);

  // 把轉換好了的整數部分和小數部分重新拼湊一個新的字符串

  String newS = part + part;

  return newS;

  }

  /**

  * 對傳入的數進行四捨五入操作

  * @param s String 從命令行輸入的那個數

  * @return 四捨五入後的新值

  */

  private String roundString(String s) {

  // 如果傳入的是空串則繼續返回空串

  if(equals(s)) {

  return ;

  }

  // 將這個數轉換成 double 類型並對其進行四捨五入操作

  double d = DoubleparseDouble(s);

  // 此操作作用在小數點後兩位上

  d = (d * + ) / ;

  // 將 d 進行格式化

  s = new javatextDecimalFormat(##)format(d);

  // 以小數點為界分割這個字符串

  int index = sindexOf();

  // 這個數的整數部分

  String intOnly = ssubstring( index);

  // 規定數值的最大長度只能到萬億單位否則返回

  if(intOnlylength() > ) {

  Systemoutprintln(輸入數據過大!(整數部分最多位!));

  return ;

  }

  // 這個數的小數部分

  String smallOnly = ssubstring(index + );

  // 如果小數部分大於兩位只截取小數點後兩位

  if(smallOnlylength() > ) {

  String roundSmall = smallOnlysubstring( );

  // 把整數部分和新截取的小數部分重新拼湊這個字符串

  s = intOnly + + roundSmall;

  }

  return s;

  }

  /**

  * 把傳入的數轉換為中文金額大寫形式

  * @param flag int 標志位 表示轉換整數部分 表示轉換小數部分

  * @param s String 要轉換的字符串

  * @return 轉換好的帶單位的中文金額大寫形式

  */

  private String numFormat(int flag String s) {

  int sLength = slength();

  // 貨幣大寫形式

  String bigLetter[] = { };

  // 貨幣單位

  String unit[] = {

  // 拾萬位到仟萬位

  

  // 億位到萬億位

   };

  String small[] = { };

  // 用來存放轉換後的新字符串

  String newS = ;

  // 逐位替換為中文大寫形式

  for(int i = ; i < sLength; i ++) {

  if(flag == ) {

  // 轉換整數部分為中文大寫形式(帶單位)

  newS = newS + bigLetter[scharAt(i) ] + unit[sLength i ];

  } else if(flag == ) {

  // 轉換小數部分(帶單位)

  newS = newS + bigLetter[scharAt(i) ] + small[sLength i ];

  }

  }

  return newS;

  } 

  /**

  * 把已經轉換好的中文金額大寫形式加以改進清理這個字

  * 符串裡面多余的零讓這個字符串變得更加可觀

  * 注傳入的這個數應該是經過 splitNum() 方法進行處理這個字

  * 符串應該已經是用中文金額大寫形式表示的

  * @param s String 已經轉換好的字符串

  * @return 改進後的字符串

  */

  private String cleanZero(String s) {

  // 如果傳入的是空串則繼續返回空串

  if(equals(s)) {

  return ;

  }

  // 如果用戶開始輸入了很多 去掉字符串前面多余的使其看上去更符合習慣

  while(scharAt() == ) {

  // 將字符串中的 和它對應的單位去掉

  s = ssubstring();

  // 如果用戶當初輸入的時候只輸入了 則只返回一個

  if(slength() == ) {

  return ;

  }

  }

  // 字符串中存在多個在一起的時候只讀出一個並省略多余的單位

  /* 由於本人對算法的研究太菜了只能用個正則表達式去轉換了各位大蝦別介意哈 */

  String regex[] = {零仟 零佰 零拾};

  String regex[] = {零億 零萬 零元};

  String regex[] = { };

  String regex[] = {零角 零分};

  // 第一輪轉換把 零仟 零佰零拾等字符串替換成一個

  for(int i = ; i < ; i ++) {

  s = sreplaceAll(regex[i] );

  }

  // 第二輪轉換考慮 零億零萬零元等情況

  // 這些單位有些情況是不能省的需要保留下來

  for(int i = ; i < ; i ++) {

  // 當第一輪轉換過後有可能有很多個零疊在一起

  // 要把很多個重復的零變成一個零

  s = sreplaceAll(零零零 );

  s = sreplaceAll(零零 );

  s = sreplaceAll(regex[i] regex[i]);

  }

  // 第三輪轉換把零角零分字符串省略

  for(int i = ; i < ; i ++) {

  s = sreplaceAll(regex[i] );

  }

  // 當之間全部是的時候忽略億萬單位只保留一個

  s = sreplaceAll(億萬 );

  return s;

  }

  }


From:http://tw.wingwit.com/Article/program/Java/hx/201311/27056.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.