软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 编程语言 -> 阿拉伯数字与中文数字的转换 -> 正文阅读

[编程语言]阿拉伯数字与中文数字的转换


今天继续看《算法的乐趣》,学习了阿拉伯数字与中文数字的转化。
汉字用零一二三四五六七八九作为基本计数,与阿拉伯数字靠数字偏移位置的权位不一样,中文数字是才有“数字+权位”的方式组成数字,比如百,千,万。
中文数字每个数字后都会跟上一个权位,权位就是数字的量值,相当于阿拉伯数字的数位。
中文计数以万为小节,万以下没有节权,万之上是亿为节权。
中文还有一个特点是多变的“零”,大概总结为三个规则:
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);
	}
	
}

下面的图片是我的测试结果:
第一幅图是阿拉伯数字转化成中文:
[img]http://img.blog.csdn.net/20160403224831210?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
第二张图片是中文数字转化成阿拉伯数字的:
[img]http://img.blog.csdn.net/20160403224935273?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center





这个数字转化算法,我看了几个小时才看懂一点点,然后在编程的时候,遇到了诸多问题,但是我最后都是独自一个个解决了,没有问别人,遇到了一些基本数据类型的问题,比如int型不能超过21亿," "两个点的是字符串类型,' '一个点的是字符类型,这个问题我在传入HashMap队列中的时候就卡得我很烦躁,传入的字符串类型,然后用字符串的CharAt()去调用,结果当然是出现异常错误,无法编译了。
还有用了一个没有必要的二重循环去检测,其实没有必要,队列有现成的方法让我去用,二重循环中还出现了死循环,在第二重里写错成了i++(其实应该是j++),导致循环不断。




算法学习之路不易,但是贵在坚持,我在编程这几个小时里常常想不出解决方案,遇到bug无法解决,但是又没有人问。[img]http://static.blog.csdn.net/xheditor/xheditor_emot/default/fastcry.gif


但是没关系,我坚持了下来,解决了我遇到的一切问题,在算法这条路上再前进了一小步,我相信我以后的IT之路一定可以越走越远,越走越宽。[img]http://static.blog.csdn.net/xheditor/xheditor_emot/default/struggle.gif
......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-04-04 00:13:46  
编程语言 最新文章
Java面试题(1)
ReactiveX序列——RxSwift
C++STL之ACM相关知识大全
c++中vector向量几种情况的总结(向量指针,
SSH框架整合demo
JAX
UVA
curl备忘(1)
C#机房重构——万事开头难(二)
OJ刷题
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年1日历
2018-1-23 4:03:14
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --