posts - 20,  comments - 2,  trackbacks - 0

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

          聲明:本文系JavaEye網(wǎng)站發(fā)布的原創(chuàng)博客文章,未經(jīng)作者書面許可,嚴禁任何網(wǎng)站轉(zhuǎn)載本文,否則必將追究法律責任!

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

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 星座| 虎林市| 姜堰市| 贵阳市| 西昌市| 陆川县| 耿马| 镇安县| 德州市| 新郑市| 临泽县| 洮南市| 商丘市| 通州市| 桐乡市| 辽源市| 共和县| 营山县| 广昌县| 根河市| 天气| 西充县| 肇东市| 连江县| 莎车县| 遂溪县| 马公市| 平昌县| 涞源县| 博爱县| 汉中市| 芜湖县| 广州市| 武乡县| 威远县| 绥阳县| 荥经县| 吴旗县| 潞西市| 荔波县| 托里县|