阿拉伯數字與中文數字的轉換----------相互轉化


今天繼續看《算法的樂趣》,學習了阿拉伯數字與中文數字的轉化。

漢字用零一二三四五六七八九作為基本計數,與阿拉伯數字靠數字偏移位置的權位不一樣。中文數字是才有“數字+權位”的方式組成數字,比方百,千,萬。

中文數字每一個數字后都會跟上一個權位。權位就是數字的量值,相當於阿拉伯數字的數位。

中文計數以萬為小節,萬下面沒有節權,萬之上是億為節權。

中文另一個特點是多變的“零”,大概總結為三個規則:

1.以10000為小節。小節的結尾即使是0,也不使用“零”。

2.小節內兩個非0數字之間要使用“零”。

3.當小節的“千”位是0時,若本小節的前一小節無其它數字。則不用“零”,否則就要用“零”。


算法設計:

首先定義三個字符串數組,存放數字位、節權位、權位

然后再分兩個方法實現,一個實現節權的操作處理,另一個實現小節內的操作。


第二個程序是實現中文數字轉化為阿拉伯數字,這個我看不懂書上的一小部分代碼。可是我讀懂了作者的思想。所以我自己寫了一個與書上不一樣的算法出來,可是思想是一樣的。

都是通過節權處分里小節,然后逐個小節計算,然后再合並得到結果。

以下是我的代碼:

</pre><pre name="code" class="java">package 阿拉伯數字與中文數字;

public class Main {
	public static void main(String[] args) {
		Main ma = new Main();
		Tool to = new Tool();
		ma.initMain();
	}
	public void initMain(){
		testNumberToChinese();
		System.out.println("————————————————————————————————————————");
		testChineseToNumber();
	}
	public void testNumberToChinese(){
		NumberChangeToChinese numToChinese = new NumberChangeToChinese();
		System.out.println("0:"+numToChinese.numberToChinese(0));
		System.out.println("1:"+numToChinese.numberToChinese(1));
		System.out.println("2:"+numToChinese.numberToChinese(2));
		System.out.println("3:"+numToChinese.numberToChinese(3));
		System.out.println("4:"+numToChinese.numberToChinese(4));
		System.out.println("5:"+numToChinese.numberToChinese(5));
		System.out.println("6:"+numToChinese.numberToChinese(6));
		System.out.println("7:"+numToChinese.numberToChinese(7));
		System.out.println("8:"+numToChinese.numberToChinese(8));
		System.out.println("9:"+numToChinese.numberToChinese(9));
		System.out.println("10:"+numToChinese.numberToChinese(10));
		System.out.println("11:"+numToChinese.numberToChinese(11));
		System.out.println("110:"+numToChinese.numberToChinese(110));
		System.out.println("111:"+numToChinese.numberToChinese(111));
		System.out.println("100:"+numToChinese.numberToChinese(100));
		System.out.println("102:"+numToChinese.numberToChinese(102));
		System.out.println("1020:"+numToChinese.numberToChinese(1020));
		System.out.println("1001:"+numToChinese.numberToChinese(1001));
		System.out.println("1015:"+numToChinese.numberToChinese(1015));
		System.out.println("1000:"+numToChinese.numberToChinese(1000));
		System.out.println("10000:"+numToChinese.numberToChinese(10000));
		System.out.println("20010"+numToChinese.numberToChinese(20010));
		System.out.println("20001"+numToChinese.numberToChinese(20001));
		System.out.println("100000:"+numToChinese.numberToChinese(100000));
		System.out.println("1000000:"+numToChinese.numberToChinese(1000000));
		System.out.println("10000000"+numToChinese.numberToChinese(10000000));
		System.out.println("100000000:"+numToChinese.numberToChinese(100000000));
		System.out.println("1000000000"+numToChinese.numberToChinese(1000000000));
		System.out.println("2000105"+numToChinese.numberToChinese(2000105));
		System.out.println("20001007:"+numToChinese.numberToChinese(20001007));
		System.out.println("2005010010:"+numToChinese.numberToChinese(2005010010));
	}
	public void testChineseToNumber(){
		ChineseChangeToNumber chineseToNumber = new ChineseChangeToNumber();
		System.out.println("二十億零五千五百零一萬四千零一十:"+chineseToNumber.ChineseToNumber("二十億零五千五百零一萬四千零一十"));
		System.out.println("二千萬一千零七:"+chineseToNumber.ChineseToNumber("二千萬一千零七"));
		System.out.println("二萬零一:"+chineseToNumber.ChineseToNumber("二萬零一"));
		System.out.println("二萬零一十:"+chineseToNumber.ChineseToNumber("二萬零一十"));
		System.out.println("一萬:"+chineseToNumber.ChineseToNumber("一萬"));
		System.out.println("一千零一十五:"+chineseToNumber.ChineseToNumber("一千零一十五"));
		System.out.println("一千:"+chineseToNumber.ChineseToNumber("一千"));
		System.out.println("一億:"+chineseToNumber.ChineseToNumber("一億"));
		
	}
}

這是主類,用於啟動程序和測試。

package 阿拉伯數字與中文數字;

public class NumberChangeToChinese {
	public String numberToChinese(int num){//轉化一個阿拉伯數字為中文字符串
		if(num == 0){
			return "零";
		}
		int unitPos = 0;//節權位標識
		String All = new String();
		String chineseNum = new String();//中文數字字符串
		boolean needZero = false;//下一小結是否須要補零
		String strIns = new String();
		while(num>0){
			int section = num%10000;//取最后面的那一個小節
			if(needZero){//推斷上一小節千位是否為零。為零就要加上零
				All = Tool.chnNumChar[0] + All;
			}
			chineseNum = sectionTOChinese(section,chineseNum);//處理當前小節的數字,然后用chineseNum記錄當前小節數字
			if( section!=0 ){//此處用if else 選擇語句來運行加節權位
				strIns = Tool.chnUnitSection[unitPos];//當小節不為0。就加上節權位
				chineseNum = chineseNum + strIns;
			}else{
				strIns = Tool.chnUnitSection[0];//否則不用加
				chineseNum = strIns + chineseNum;
			}
			All = chineseNum+All;
			chineseNum = "";
			needZero = (section<1000) && (section>0);
			num = num/10000;
			unitPos++;
		}
		return All;
	}
	public String sectionTOChinese(int section,String chineseNum){
		String setionChinese = new String();//小節部分用獨立函數操作
		int unitPos = 0;//小節內部的權值計數器
		boolean zero = true;//小節內部的制零推斷。每一個小節內僅僅能出現一個零
		while(section>0){
			int v = section%10;//取當前最末位的值
			if(v == 0){
				if( !zero ){
					zero = true;//須要補零的操作。確保對連續多個零僅僅是輸出一個
					chineseNum = Tool.chnNumChar[0] + chineseNum;
				}
			}else{
				zero = false;//有非零的數字。就把制零開關打開
				setionChinese = Tool.chnNumChar[v];//相應中文數字位
				setionChinese = setionChinese + Tool.chnUnitChar[unitPos];//相應中文權位
				chineseNum = setionChinese + chineseNum;
			}
			unitPos++;
			section = section/10;
		}
		
		return chineseNum;
	}
}

這第二個是阿拉伯數字轉化成中文數字的類,實現的過程大致跟書上的一樣。

以下是第三個中文轉化成阿拉伯數組的類:

package 阿拉伯數字與中文數字;

public class ChineseChangeToNumber {
	public int ChineseToNumber(String str){
		String str1 = new String();
		String str2 = new String();
		String str3 = new String();
		int k = 0;
		boolean dealflag = true;
		for(int i=0;i<str.length();i++){//先把字符串中的“零”除去
				if('零' == (str.charAt(i))){
					str = str.substring(0, i) + str.substring(i+1);
				}
		}
		String chineseNum = str;
		for(int i=0;i<chineseNum.length();i++){
			if(chineseNum.charAt(i) == '億'){
				str1 = chineseNum.substring(0,i);//截取億前面的數字,逐個對比表格。然后轉換
				k = i+1;
				dealflag = false;//已經處理
			}
			if(chineseNum.charAt(i) == '萬'){
				str2 = chineseNum.substring(k,i);
				str3 = str.substring(i+1);
				dealflag = false;//已經處理
			}
		}
		if(dealflag){//假設沒有處理
			str3 =  chineseNum;
		}
		int result = sectionChinese(str1) * 100000000 +
				sectionChinese(str2) * 10000 + sectionChinese(str3);
		return result;
	}
	
	public int sectionChinese(String str){
		int value = 0;
		int sectionNum = 0;
		for(int i=0;i<str.length();i++){
			int v = (int) Tool.intList.get(str.charAt(i));
			if( v == 10 || v == 100 || v == 1000 ){//假設數值是權位則相乘
				sectionNum = v * sectionNum;
				value = value + sectionNum;
			}else if(i == str.length()-1){
				value = value + v;
			}else{
				sectionNum = v;
			}
		}
		return value;
	}
}


這真真正正是我自己一個個字寫的,都是通過思考得出的結果,可能有些不嚴謹,可是確實能夠實現。

第四個是工具類,存放字符串數據用的。

package 阿拉伯數字與中文數字;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

public class Tool {
	//數字位
	public static String[] chnNumChar = {"零","一","二","三","四","五","六","七","八","九"};
	public static char[] chnNumChinese = {'零','一','二','三','四','五','六','七','八','九'};
	//節權位
	public static String[] chnUnitSection = {"","萬","億","萬億"};	
	//權位
	public static String[] chnUnitChar = {"","十","百","千"};
	public static HashMap intList = new HashMap();
	static{
		for(int i=0;i<chnNumChar.length;i++){
			intList.put(chnNumChinese[i], i);
		}
		
		intList.put('十',10);
		intList.put('百',100);
		intList.put('千', 1000);
	}
	
}

以下的圖片是我的測試結果:

第一幅圖是阿拉伯數字轉化成中文:




第二張圖片是中文數字轉化成阿拉伯數字的:




這個數字轉化算法,我看了幾個小時才看懂一點點,然后在編程的時候,遇到了諸多問題,可是我最后都是獨自一個個攻克了,沒有問別人,遇到了一些基本數據類型的問題,比方int型不能超過21億。" "兩個點的是字符串類型,' '一個點的是字符類型。這個問題我在傳入HashMap隊列中的時候就卡得我非常煩躁,傳入的字符串類型。然后用字符串的CharAt()去調用,結果當然是出現異常錯誤。無法編譯了。

還實用了一個沒有必要的二重循環去檢測,事實上沒有必要,隊列有現成的方法讓我去用。二重循環中還出現了死循環。在第二重里寫錯成了i++(事實上應該是j++),導致循環不斷。



算法學習之路不易,可是貴在堅持,我在編程這幾個小時里經常想不出解決方式。遇到bug無法解決,可是又沒有人問。快哭了


可是沒關系,我堅持了下來,攻克了我遇到的一切問題。在算法這條路上再前進了一小步,我相信我以后的IT之路一定能夠越走越遠,越走越寬。

奮斗


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM