相信大家也见过这道题 分享一下我这个比较笨的方法:
*思路:在本题原有的基础上增加两位小数,即角和分。操作方法如下:
* 1,明确要转换的源:
* 阿拉伯数字每一位为可以是0-9,对应中国传统数字零-玖。这是就可以定义一个数组中,这个数组从角标
* 0-9分别存放的是中国传统数字壹-玖。
* 2,明确转换结果:
* 传统形式的金额是有单位的,如:拾,佰,仟,万,拾万,佰万,仟万,亿,拾亿,佰亿,仟亿等(此处只考虑到仟亿);
* 小于一的单位为角和分。例如:4080988008.89转换结果为--肆拾亿零捌仟零玖拾捌万捌仟零捌圆捌角玖分
* 3,转换方法,将键盘录入的数字转换成相应的传统数字,并且每个数字都添加上对应的单位,并把得到的结果装在一个字符串中,
* 然后再对这个字符串进行正则匹配,目的是让结果更接近人们日常书写的习惯。
*/
public class Test10 {
public static void main(String[] args) {
//提示操作者要输入数字的类型
System.out.println("请输入一个有1-2位小数的4-14位以内的小数,不能以0开头");
//定义一个简单的文本输入对象,用来输入需要处理的金额数字
Scanner in = new Scanner(System.in);
//以字符串的形式读取操作者输入的数字,并进行正则匹配,如果不是程序所需要的格式,就会报错。
String instr = in.next(); //next()是一个阻塞式方法,如果操作者不按下回车键,那么程序会一直在等待。
String regex = "[1-9]\\d{1,11}\\.\\d{1,2}";
String str = null ;
boolean flag = instr.matches(regex);
//如果此字符串格式正确,程序会调用转换金额的方法。
if(flag){
str = moneyChange(instr);
changeValue(str);
}
//如果此字符串格式错误,程序会提示操作者
else{
System.out.println("格式错误,请重新输入!");
return;
}
}
//通过一些列的正则匹配让转换的结果更类似中国的传统形式
public static void changeValue(String str){
//去掉亿位上空缺的部分
String str1 = str.replaceAll("零零零零亿","零");
//去掉万位上空缺的部分 4600000566.55--> 肆拾陆亿零零零零万零伍佰陆拾陆圆伍角伍分
String str2 = str1.replaceAll("零零零零万","零");
//去掉多余的零46000566.55-->肆仟陆佰零零万零伍佰陆拾陆圆伍角伍分
String str3 = str2.replaceAll("零+万","万零");
String str4 = str3.replaceAll("零+亿","亿零");
String str5 = str4.replaceAll("零+圆","圆");
//去掉由上述转换为零+的情况4690000566.55 -->肆拾陆亿玖仟万零零伍佰陆拾陆圆伍角伍分
String str6 = str5.replaceAll("(.)\\1+","$1");
System.out.println(" 转换结果-->"+str6);
}
/*转换方法:传统形式在十百千前面加上单位,有万和亿两种,
这样就使得数字增加4位就需增加一个万的单位,增加8位就需要增加一个亿位。
定义一个接受String类型参数的方法,该方法用于处理获得到的字符串,返回值类型为String
*/
public static String moneyChange(String str){
int x = 0;
int y = 0;
//定义一个字符串缓冲区,用来操作获得的字符。
StringBuffer sb = new StringBuffer("");
/*判断由键盘录入的字符串中有无小数点(因为在程序开始前已声明需要两位数的小数,这部分显得多余;但是,如果不声明
的话,操作者可能输入的数字是不一样的,所以这里保留了这种判断。程序后面使用的递归方法,可以先去掉整数部分去
转换小数部分,然后再转换整数数部分,最后将两者转换的和进行处理)*/
x = str.lastIndexOf(".");
if(x==-1){ //操作整数部分
x = str.length();
//使用toCharArray方法将传入的字符串对象变成字节数组进行操作,因为0-9是可以转换为字节的。
char[] chr1 = str.toCharArray();
//定义一个字符串缓冲区用来存放每一个字节对应的转换后的部分
StringBuffer sb1 = null;
//对整数部分的字符串进行遍历
for(x = chr1.length-1,y=0;x>=0;x--,y++){
sb1 = new StringBuffer("");
//将遍历到的每一个字符调用changeNum方法,找到它所对应的中国传统数字,并将它存到缓冲区中。
if(x != chr1.length-1 ){
//这里没有添加个位上的数字
sb1.append(changeNum(chr1[x]));
}
//从char数字的角标最大的一位查起,一次递减,最大角标的那个数字对应的是传统金额的个位,所以单位一次递增
if(chr1[x] != '0'){
switch (y%4){
//每隔4位,需要在数字后面增加对应的单位
case 1:sb1.append("拾");break;
case 2:sb1.append("佰");break;
case 3:sb1.append("仟");break;
default :break;
}
}
//将个位上的数子转换后添加到数组中
if(y == 0)
sb1.append(changeNum(chr1[x]));
/*随着y++,需要再对y进行判断,先判断y%8是否为零,即是否到了亿这位,如果没有
再判断y%4是否为零,即是否到了万位。
*/
if(y>0 && y%8==0)
sb1.append("亿"); //如果到亿这位,就想缓冲区添加 亿 字
else if(y>0 && y%4==0)
sb1.append("万");//如果到万这位,就想缓冲区添加 万 字
//然后将整数部分的缓冲区数据添加到整体的缓冲区中
sb = sb1.append(sb);
}
//整数部分最后一个字符为 圆
return sb.append("圆").toString();
}
//程序首先执行的是小数部分
else if(x!=-1){
String str3 = null;
x = str.lastIndexOf(".");
//分别获取小数部分和整数部分的字符串表现形式 str2 str3
String str2 = str.substring(0, x);
str3 = str.substring(x+1,str.length());
String str4 = moneyChange(str2); //使用递归的方法,将整数部分的字符串对象str2作为参数传递给本类方法。
//对小数部分进行处理,分别判断第一位小数和第二位小数的值是否大于零,
char[] chr2 = str3.toCharArray();
//如果是一位小数,则直接添加该位的数字值和对应的单位
if(chr2.length==1)
if(chr2[0]!='0') //.append("零")
sb.append(changeNum(chr2[0])).append("角").toString();
//如果是两位小数,则需要判断它们是否为0
if(chr2.length==2){
//全为零的情况,就不需要做任何处理
//第一个为零,第二个不为零
if(chr2[0]=='0'&& chr2[1]!='0' )
sb.append("零");
//第一个不为零,此时不考虑第二个
if(chr2[0]!='0')
sb.append(changeNum(chr2[0])).append("角").toString();
//第二个不为零,此时不考虑第一个
if(chr2[1]!='0')
sb.append(changeNum(chr2[1])).append("分").toString();
}
//最后将两者转换的和返回
return (str4+sb.toString());
}
else
return null;
}
/*定义一个获取字符数组中元素的方法,该方法接受的是一个char类型的参数,
利用该char型参数和'0'的差,该差值为int型,再用这个差值作为角标去符数组中
获取阿拉伯数组所对应的中国传统数字。所以该方法的返回值为String
*/
public static String changeNum(char c){
//定义一个字符数组,用来存放从零-玖这个9个字符,
String[] n={"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
return n[c-'0'];
}
}
|
|