马程序员学习笔记——人民币金额大写转换

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

需求:金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。

分析:对于小数位,由于现在最小面值是分,所以只取两位小数。

对于整数位,比较难解决的是多个零连续出现时的表示方法,这个现象是这样的,当多个零连续出现时,一般在中文中只显示一个零,

比如1001,就是“壹仟零壹元”,但如果这个0是处于关键位是(万、亿位),那么这个零的单位就不能省了,比如100000,就是“壹拾万元整”。


然后根据整数部分和小数部分的不同情况,将这两部分合理相加


ok,上代码

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ConvertCurrency {

	/**
	 * 金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。
	 */
	public static void main(String[] args) {
		//因为最小单位就是分,所以暂时设定最小只能输入两个小数,整数不限
		String str = "¥3540.01";
		parse(str);
		integrated();
	}
	
	public static void parse(String str) {
		//定义一个正则表达式,作用:去掉整数位最前面的0,把整数位(第一组)和小数位(第3组)区别开来
		Pattern p = Pattern.compile("¥{0,1}0*(\\d{1,})(\\.(\\d{1,2})){0,1}");
		Matcher m = p.matcher(str);
		if (p.matcher(str).matches()) {
			while (m.find()) {
				String intPart = m.group(1);
//				转换整数部分
				transInt(intPart);
				String decimalPart = m.group(3);
//				转换小数部分
				transDec(decimalPart);
			}
		} else {
			System.out.println("格式不对");
			return;
		}
	}
	
	//最后输出时,把整数部分和小数部分整合起来
	public static void integrated() {
		if (intSB.length() == 0) {
			if (decSB.length() == 0) {
				System.out.println("0元整");
			} else {
				System.out.println(decSB);
			}
		} else {
			if (decSB.length() == 0) {
				System.out.println(intSB + "整");
			} else {
				System.out.print(intSB);
				System.out.println(decSB);
			}
		}
		
	}
	
	static StringBuilder intSB = new StringBuilder(); 
	public static void transInt(String intPart) {
		long sum = Long.valueOf(intPart);	//之所以用Long,是因为int只有4个字节,最多支持21亿,Long的话,2的63次方,世界首富看了都傻眼
		if (sum == 0) {
			return;		//如果整数部分是0的话
		} else {
			intSB.insert(0, "元");
		}
		
		int pos = 0;	//记录当前处于整个数字中的第几位(从低往高算)
		boolean isZeroSequence = false;		//出现连续0的标志
		while (sum != 0) {
			pos++;		//当前位数
			int temp = (int)(sum % 10);		//得到当前位是几
			if (temp == 0) {
				addUnit(pos, true);		//先加上单位
				if (!isZeroSequence) {	//如果不是连续的出现0
					if (pos != 1) {		//如果不是个位的情况下,因为如果个位是0,可以直接跳过
						String str = getChin(temp);
						intSB.insert(0, str);
					}
					isZeroSequence = true;	//因为已经出现了一次0,所以先标记上
				}
				sum = sum / 10;		//去掉已经分析的一位
			} else {
				isZeroSequence = false;  //既然这位不是0,那么把连续0的状态清除
				addUnit(pos, false);	//加上单位
				String str = getChin(temp);
				intSB.insert(0, str);
				sum = sum / 10;		//去掉已经分析的一位
			}
		}
		
	}
	
	public static void addUnit(int pos, boolean isZero) {
		String unit;
		if (!isZero || pos%4==1) {	//如果当前为不是0,或者当前位是0,但这个0处于万、亿位置上
			if (pos <= 9) {		//小于9位数的情况下
				unit = getUnit(pos);
				intSB.insert(0, unit);
			} else {			//如果已经大于9位数
				int tempPos = pos - 8;
				while (tempPos > 8) {
					tempPos -= 8;
				}
				unit = getUnit(tempPos);
				intSB.insert(0, unit);
			}
		}
	}
	
	static StringBuilder decSB = new StringBuilder();
	public static void transDec(String decPart) {
		if (decPart == null) {
//			decSB.append("整");  //如果没有小数位,那就是整数
			return;
		}
		int i = Integer.parseInt(decPart);
		if (i == 0) {
//			decSB.append("整");  //如果没有小数位,那就是整数
			return;
		}
		if (decPart.length() == 1) {	//如果只有一位小数的话
			decSB.append(getChin(i));
			decSB.append(getUnit(-1));
		} else if (decPart.length() == 2) {		//如果有两位小数的话
			if (i<10) {							//两位小数转化过来只有一位,那么肯定是0角
				decSB.append(getChin(0));
				decSB.append(getChin(i));
				decSB.append(getUnit(-2));
			} else {
				int jiao = i/10;
				decSB.append(getChin(jiao));
				decSB.append(getUnit(-1));
				int fen = i%10;
				if (fen == 0) return;
				decSB.append(getChin(fen));
				decSB.append(getUnit(-2));
			}
		}
	}
	
	
	
//	壹拾贰亿叁仟肆佰伍拾陆万柒仟捌佰玖拾元整零
	public static String getChin(int i) {
		switch (i) {
		case 0 : return "零";
		case 1 : return "壹";
		case 2 : return "贰";
		case 3 : return "叁";
		case 4 : return "肆";
		case 5 : return "伍";
		case 6 : return "陆";
		case 7 : return "柒";
		case 8 : return "捌";
		case 9 : return "玖";
		default :
			return "error1";
		}
	}
//	计算不大于9位数的单位
	public static String getUnit(int i) {
		switch (i) {
		case -2 : return "分";
		case -1 : return "角";
		case 1 : return "";		//如果小于9位数,这个可以输出“元”,但这样一来,对大于9位数的操作就比较麻烦了,所以把“元这个单位放到62行上”
		case 2 : return "拾";
		case 3 : return "佰";
		case 4 : return "仟";
		case 5 : return "万";
		case 6 : return "拾";
		case 7 : return "佰";
		case 8 : return "仟";
		case 9 : return "亿";
		default :
			return "error2";
		}
	}
	
}


---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值