posts - 20,  comments - 2,  trackbacks - 0

          作者: tianshi0253  鏈接:http://tianshi0253.javaeye.com/blog/202928  發表時間: 2008年06月13日

          聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!

          package com.jqqd.ywc;
          
          /**
           * 程序目的: 從命令行接收一個數,并將其轉化為中文金額的大寫方式 例如 123.45 --> 壹佰貳拾叁元肆角伍分
           * 
           * @author LovinChan
           * 
           * 看到網上有很多這樣的例子程序,不過覺得很不滿意。有些程序我從命名上就覺得 實在是不符合規范,程序里面的算法沒有讓人明白得很清楚的注釋,讀上去覺得有
           * 點難度,可讀性不強。而且很多程序還存在不少bug,隨便一測就測出來了。 所以本人還是決定重新寫一下這個程序,并且盡量做到消除不必要的bug。這個程
           * 序我沒有用什么很精妙的算法,不過用了一些Java類庫中的類,像是正則表達式之類
           * 的東西。由于本人對算法不怎么在行,在做轉換操作的時候用的是很笨的方法。望各位 大蝦海涵,呵呵。
           * 
           * 程序的注釋我盡量寫得詳細一點,如果覺得這個程序哪里有問題或者是哪里有改進的 地方歡迎隨時跟我交流。 我的msn:egg.chenlw@gmail.com
           * QQ:543669516(注上為什么加我就可以了) 我的blog:http://hi.baidu.com/egg_chen 歡迎交流
           */
          public class Trans2RMB {
          
          	/**
          	 * 測試程序的可行性
          	 * 
          	 * @param args
          	 */
          	public static void main(String[] args) {
          		System.out.println("--------將數字轉換成中文金額的大寫形式------------\n");
          		Trans2RMB t2r = new Trans2RMB();
          		String s = t2r.cleanZero(t2r.splitNum(t2r.roundString(t2r.getNum())));
          		// 如果轉換過后是一個空串,則不輸出屏幕
          		if (!"".equals(s)) {
          			System.out.println("轉換成中文后為:" + s);
          			;
          		}
          		System.out.println("\n---------------------------------------------");
          	}
          
          	/**
          	 * 從命令行接收一個數,在其中調用 checkNum() 方法對其進行 驗證,并返回相應的值
          	 * 
          	 * @return 如果輸入合法,返回輸入的這個數
          	 */
          	private String getNum() {
          		String s = null;
          		System.out.println("請輸入一個數字(精確到小數點后兩位):");
          		// 從命令行輸入這個浮點數
          		java.util.Scanner scanner = new java.util.Scanner(System.in);
          		s = scanner.next();
          		// 判斷用戶輸入是否合法
          		// 若合法,返回這個值;若非法返回 "0"
          		if (this.checkNum(s)) {
          			return s;
          		} else {
          			return "";
          		}
          	}
          
          	/**
          	 * 判斷用戶輸入的數據是否合法,用戶只能輸入大于零的數字,不能輸入其它字符
          	 * 
          	 * @param s
          	 *            String
          	 * @return 如果用戶輸入數據合法,返回 true,否則返回 false
          	 */
          	private boolean checkNum(String s) {
          		// 如果用戶輸入的數里有非數字字符,則視為非法數據,返回 false
          		try {
          			float f = Float.valueOf(s);
          			// 如果這個數小于零則視為非法數據,返回 false
          			if (f < 0) {
          				System.out.println("非法數據,請檢查!");
          				return false;
          			} else {
          				return true;
          			}
          		} catch (NumberFormatException e) {
          			System.out.println("非法數據,請檢查!");
          			return false;
          		}
          	}
          
          	/**
          	 * 把用戶輸入的數以小數點為界分割開來,并調用 numFormat() 方法 進行相應的中文金額大寫形式的轉換 注:傳入的這個數應該是經過
          	 * roundString() 方法進行了四舍五入操作的
          	 * 
          	 * @param s
          	 *            String
          	 * @return 轉換好的中文金額大寫形式的字符串
          	 */
          	private String splitNum(String s) {
          		// 如果傳入的是空串則繼續返回空串
          		if ("".equals(s)) {
          			return "";
          		}
          		// 以小數點為界分割這個字符串
          		int index = s.indexOf(".");
          		// 截取并轉換這個數的整數部分
          		String intOnly = s.substring(0, index);
          		String part1 = this.numFormat(1, intOnly);
          		// 截取并轉換這個數的小數部分
          		String smallOnly = s.substring(index + 1);
          		String part2 = this.numFormat(2, smallOnly);
          		// 把轉換好了的整數部分和小數部分重新拼湊一個新的字符串
          		String newS = part1 + part2;
          		return newS;
          	}
          
          	/**
          	 * 對傳入的數進行四舍五入操作
          	 * 
          	 * @param s
          	 *            String 從命令行輸入的那個數
          	 * @return 四舍五入后的新值
          	 */
          	private String roundString(String s) {
          		// 如果傳入的是空串則繼續返回空串
          		if ("".equals(s)) {
          			return "";
          		}
          		// 將這個數轉換成 double 類型,并對其進行四舍五入操作
          		double d = Double.parseDouble(s);
          		// 此操作作用在小數點后兩位上
          		d = (d * 100 + 0.5) / 100;
          		// 將 d 進行格式化
          		s = new java.text.DecimalFormat("##0.000").format(d);
          		// 以小數點為界分割這個字符串
          		int index = s.indexOf(".");
          		// 這個數的整數部分
          		String intOnly = s.substring(0, index);
          		// 規定數值的最大長度只能到萬億單位,否則返回 "0"
          		if (intOnly.length() > 13) {
          			System.out.println("輸入數據過大!(整數部分最多13位!)");
          			return "";
          		}
          		// 這個數的小數部分
          		String smallOnly = s.substring(index + 1);
          		// 如果小數部分大于兩位,只截取小數點后兩位
          		if (smallOnly.length() > 2) {
          			String roundSmall = smallOnly.substring(0, 2);
          			// 把整數部分和新截取的小數部分重新拼湊這個字符串
          			s = intOnly + "." + roundSmall;
          		}
          		return s;
          	}
          
          	/**
          	 * 把傳入的數轉換為中文金額大寫形式
          	 * 
          	 * @param flag
          	 *            int 標志位,1 表示轉換整數部分,0 表示轉換小數部分
          	 * @param s
          	 *            String 要轉換的字符串
          	 * @return 轉換好的帶單位的中文金額大寫形式
          	 */
          	private String numFormat(int flag, String s) {
          		int sLength = s.length();
          		// 貨幣大寫形式
          		String bigLetter[] = { "零", "壹", "貳", "叁", "肆", "伍", "陸", "柒", "捌", "玖" };
          		// 貨幣單位
          		String unit[] = { "元", "拾", "佰", "仟", "萬",
          		// 拾萬位到仟萬位
          				"拾", "佰", "仟",
          				// 億位到萬億位
          				"億", "拾", "佰", "仟", "萬" };
          		String small[] = { "分", "角" };
          		// 用來存放轉換后的新字符串
          		String newS = "";
          		// 逐位替換為中文大寫形式
          		for (int i = 0; i < sLength; i++) {
          			if (flag == 1) {
          				// 轉換整數部分為中文大寫形式(帶單位)
          				newS = newS + bigLetter[s.charAt(i) - 48]
          						+ unit[sLength - i - 1];
          			} else if (flag == 2) {
          				// 轉換小數部分(帶單位)
          				newS = newS + bigLetter[s.charAt(i) - 48]
          						+ small[sLength - i - 1];
          			}
          		}
          		return newS;
          	}
          
          	/**
          	 * 把已經轉換好的中文金額大寫形式加以改進,清理這個字 符串里面多余的零,讓這個字符串變得更加可觀 注:傳入的這個數應該是經過 splitNum()
          	 * 方法進行處理,這個字 符串應該已經是用中文金額大寫形式表示的
          	 * 
          	 * @param s
          	 *            String 已經轉換好的字符串
          	 * @return 改進后的字符串
          	 */
          	private String cleanZero(String s) {
          		// 如果傳入的是空串則繼續返回空串
          		if ("".equals(s)) {
          			return "";
          		}
          		// 如果用戶開始輸入了很多 0 去掉字符串前面多余的'零',使其看上去更符合習慣
          		while (s.charAt(0) == '零') {
          			// 將字符串中的 "零" 和它對應的單位去掉
          			s = s.substring(2);
          			// 如果用戶當初輸入的時候只輸入了 0,則只返回一個 "零"
          			if (s.length() == 0) {
          				return "零";
          			}
          		}
          		// 字符串中存在多個'零'在一起的時候只讀出一個'零',并省略多余的單位
          		/* 由于本人對算法的研究太菜了,只能用4個正則表達式去轉換了,各位大蝦別介意哈... */
          		String regex1[] = { "零仟", "零佰", "零拾" };
          		String regex2[] = { "零億", "零萬", "零元" };
          		String regex3[] = { "億", "萬", "元" };
          		String regex4[] = { "零角", "零分" };
          		// 第一輪轉換把 "零仟", 零佰","零拾"等字符串替換成一個"零"
          		for (int i = 0; i < 3; i++) {
          			s = s.replaceAll(regex1[i], "零");
          		}
          		// 第二輪轉換考慮 "零億","零萬","零元"等情況
          		// "億","萬","元"這些單位有些情況是不能省的,需要保留下來
          		for (int i = 0; i < 3; i++) {
          			// 當第一輪轉換過后有可能有很多個零疊在一起
          			// 要把很多個重復的零變成一個零
          			s = s.replaceAll("零零零", "零");
          			s = s.replaceAll("零零", "零");
          			s = s.replaceAll(regex2[i], regex3[i]);
          		}
          		// 第三輪轉換把"零角","零分"字符串省略
          		for (int i = 0; i < 2; i++) {
          			s = s.replaceAll(regex4[i], "");
          		}
          		// 當"萬"到"億"之間全部是"零"的時候,忽略"億萬"單位,只保留一個"億"
          		s = s.replaceAll("億萬", "億");
          		return s;
          	}
          }
          

           


          本文的討論也很精彩,瀏覽討論>>


          JavaEye推薦




          文章來源:http://tianshi0253.javaeye.com/blog/202928
          posted on 2008-06-22 00:10 姚文超 閱讀(320) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 沁水县| 商丘市| 利川市| 荣成市| 周宁县| 渭南市| 林口县| 浦城县| 大埔县| 富源县| 高台县| 东海县| 梁平县| 明溪县| 神池县| 岳西县| 响水县| 敦煌市| 丹寨县| 洪江市| 吉林市| 浑源县| 德钦县| 抚州市| 米泉市| 休宁县| 工布江达县| 秦安县| 英山县| 佛教| 石首市| 大城县| 来凤县| 龙陵县| 兴海县| 保德县| 朝阳县| 云和县| 盱眙县| 介休市| 汽车|