黑马程序员技术交流社区

标题: 第十题: 金额转换,阿拉伯数字转换成中国传统形式。例... [打印本页]

作者: 橘子你个哈密瓜    时间: 2015-1-13 15:30
标题: 第十题: 金额转换,阿拉伯数字转换成中国传统形式。例...
相信大家也见过这道题  分享一下我这个比较笨的方法:

*思路:在本题原有的基础上增加两位小数,即角和分。操作方法如下:
*        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'];
        }
}







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2