A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© sanguodouble1 中级黑马   /  2014-5-27 01:44  /  9328 人查看  /  27 人回复  /   2 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 sanguodouble1 于 2014-5-29 22:36 编辑

需求:金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。
分析:对于小数位,由于现在最小面值是分,所以只取两位小数。
对于整数位,比较难解决的是多个零连续出现时的表示方法,当多个零连续出现时,一般在中文中只显示一个零,
比如1001,就是“壹仟零壹元”,但如果这个0是处于关键位是(万、亿位),那么这个零的单位就不能省了,比如100000,就是“壹拾万元整”。

然后根将这两部分合理相加
下面是我的代码,(做了好几小时,惭愧:o)


  1. public class ConvertCurrency {

  2.         public static void main(String[] args) {
  3.                 //因为最小单位就是分,所以暂时设定最小只能输入两个小数,整数不限
  4.                 String str = "¥3540.01";
  5.                 parse(str);
  6.                 integrated();
  7.         }
  8.         
  9.         public static void parse(String str) {
  10.                 //定义一个正则表达式,作用:去掉整数位最前面的0,把整数位(第一组)和小数位(第3组)区别开来
  11.                 Pattern p = Pattern.compile("¥{0,1}0*(\\d{1,})(\\.(\\d{1,2})){0,1}");
  12.                 Matcher m = p.matcher(str);
  13.                 if (p.matcher(str).matches()) {
  14.                         while (m.find()) {
  15.                                 String intPart = m.group(1);
  16. //                                转换整数部分
  17.                                 transInt(intPart);
  18.                                 String decimalPart = m.group(3);
  19. //                                转换小数部分
  20.                                 transDec(decimalPart);
  21.                         }
  22.                 } else {
  23.                         System.out.println("格式不对");
  24.                         return;
  25.                 }
  26.         }
  27.         
  28.         //最后输出时,把整数部分和小数部分整合起来
  29.         public static void integrated() {
  30.                 if (intSB.length() == 0) {
  31.                         if (decSB.length() == 0) {
  32.                                 System.out.println("0元整");
  33.                         } else {
  34.                                 System.out.println(decSB);
  35.                         }
  36.                 } else {
  37.                         if (decSB.length() == 0) {
  38.                                 System.out.println(intSB + "整");
  39.                         } else {
  40.                                 System.out.print(intSB);
  41.                                 System.out.println(decSB);
  42.                         }
  43.                 }
  44.                
  45.         }
  46.         
  47.         //这个用来放整数部分
  48.         static StringBuilder intSB = new StringBuilder();
  49.         public static void transInt(String intPart) {
  50.                 long sum = Long.valueOf(intPart);        //之所以用Long,是因为int只有4个字节,最多支持21亿,Long的话,2的63次方,世界首富看了都傻眼
  51.                 if (sum == 0) {
  52.                         return;                //如果整数部分是0的话
  53.                 } else {
  54.                         intSB.insert(0, "元");
  55.                 }
  56.                
  57.                 int pos = 0;        //记录当前处于整个数字中的第几位
  58.                 boolean isZeroSequence = false;                //出现连续0的标志
  59.                 while (sum != 0) {
  60.                         pos++;                //当前位数
  61.                         int temp = (int)(sum % 10);                //得到当前位是几
  62.                         if (temp == 0) {
  63.                                 addUnit(pos, true);                //先加上单位
  64.                                 if (!isZeroSequence) {        //如果不是连续的出现0
  65.                                         if (pos != 1) {                //如果不是个位的情况下,因为如果个位是0,可以直接跳过
  66.                                                 String str = getChin(temp);
  67.                                                 intSB.insert(0, str);
  68.                                         }
  69.                                         isZeroSequence = true;        //因为已经出现了一次0,所以先标记上
  70.                                 }
  71.                                 sum = sum / 10;                //去掉已经分析的一位
  72.                         } else {
  73.                                 isZeroSequence = false;  //既然这位不是0,那么把连续0的状态清除
  74.                                 addUnit(pos, false);        //加上单位
  75.                                 String str = getChin(temp);
  76.                                 intSB.insert(0, str);
  77.                                 sum = sum / 10;                //去掉已经分析的一位
  78.                         }
  79.                 }
  80.                
  81.         }
  82.         
  83.         public static void addUnit(int pos, boolean isZero) {
  84.                 String unit;
  85.                 if (!isZero || pos%4==1) {        //如果当前为不是0,或者当前位是0,但这个0处于万、亿位置上
  86.                         if (pos <= 9) {                //小于9位数的情况下
  87.                                 unit = getUnit(pos);
  88.                                 intSB.insert(0, unit);
  89.                         } else {                        //如果已经大于9位数
  90.                                 int tempPos = pos - 8;
  91.                                 while (tempPos > 8) {
  92.                                         tempPos -= 8;
  93.                                 }
  94.                                 unit = getUnit(tempPos);
  95.                                 intSB.insert(0, unit);
  96.                         }
  97.                 }
  98.         }
  99.         
  100.         //这个用来放小数部分
  101.         static StringBuilder decSB = new StringBuilder();
  102.         public static void transDec(String decPart) {
  103.                 if (decPart == null) {
  104. //                        decSB.append("整");  //如果没有小数位,那就是整数
  105.                         return;
  106.                 }
  107.                 int i = Integer.parseInt(decPart);
  108.                 if (i == 0) {
  109. //                        decSB.append("整");  //如果没有小数位,那就是整数
  110.                         return;
  111.                 }
  112.                 if (decPart.length() == 1) {        //如果只有一位小数的话
  113.                         decSB.append(getChin(i));
  114.                         decSB.append(getUnit(-1));
  115.                 } else if (decPart.length() == 2) {                //如果有两位小数的话
  116.                         if (i<10) {                                                        //两位小数转化过来只有一位,那么肯定是角位必为0
  117.                                 decSB.append(getChin(0));
  118.                                 decSB.append(getChin(i));
  119.                                 decSB.append(getUnit(-2));
  120.                         } else {
  121.                                 int jiao = i/10;
  122.                                 decSB.append(getChin(jiao));
  123.                                 decSB.append(getUnit(-1));
  124.                                 int fen = i%10;
  125.                                 if (fen == 0) return;
  126.                                 decSB.append(getChin(fen));
  127.                                 decSB.append(getUnit(-2));
  128.                         }
  129.                 }
  130.         }
  131.         
  132.         
  133.         
  134. //        壹拾贰亿叁仟肆佰伍拾陆万柒仟捌佰玖拾元整零
  135.         public static String getChin(int i) {
  136.                 switch (i) {
  137.                 case 0 : return "零";
  138.                 case 1 : return "壹";
  139.                 case 2 : return "贰";
  140.                 case 3 : return "叁";
  141.                 case 4 : return "肆";
  142.                 case 5 : return "伍";
  143.                 case 6 : return "陆";
  144.                 case 7 : return "柒";
  145.                 case 8 : return "捌";
  146.                 case 9 : return "玖";
  147.                 default :
  148.                         return "error1";
  149.                 }
  150.         }
  151. //        计算不大于9位数的单位
  152.         public static String getUnit(int i) {
  153.                 switch (i) {
  154.                 case -2 : return "分";
  155.                 case -1 : return "角";
  156.                 case 1 : return "";                //如果小于9位数,这个可以输出“元”,但这样一来,对大于9位数的操作就比较麻烦了,所以把“元这个单位放到62行上”
  157.                 case 2 : return "拾";
  158.                 case 3 : return "佰";
  159.                 case 4 : return "仟";
  160.                 case 5 : return "万";
  161.                 case 6 : return "拾";
  162.                 case 7 : return "佰";
  163.                 case 8 : return "仟";
  164.                 case 9 : return "亿";
  165.                 default :
  166.                         return "error2";
  167.                 }
  168.         }
  169. }
复制代码



不足之处,请指正,如有好的想法,欢迎交流,共同进步


评分

参与人数 1技术分 +1 收起 理由
李小然 + 1 赞一个!

查看全部评分

27 个回复

正序浏览
可以的 赞个!!!
回复 使用道具 举报
icm 中级黑马 2015-12-17 22:30:24
26#
没看懂。。。
回复 使用道具 举报
不错,学习了
回复 使用道具 举报
厉害!得向你学习啊!
回复 使用道具 举报
最后笔试,代码应该不会太多吧?
回复 使用道具 举报
不明觉厉
回复 使用道具 举报
应该是考察查表的:)
回复 使用道具 举报
这也太复杂了吧!用制表法那种方式,可以缩短很多代码!不过按照你的思路没有错!  不过用制表法的思维快多了!在开发中,就当作优化吧!!
回复 使用道具 举报
chang清 发表于 2014-6-10 13:00
我基入学测试也遇到这个题了,代码稍微比这个少一点,思想也不难理解(搞了差不多一个下午吧);分享了交流 ...

谢谢你的分享,很厉害
回复 使用道具 举报
大神很厉害啊!赞一个
回复 使用道具 举报
楼主赞!
回复 使用道具 举报
我的笔试题也是这个,最后一道提,可是我没看正则表达式啊,,郁闷死了
回复 使用道具 举报
不觉明历,表示完全看不懂啊!!
回复 使用道具 举报
完全不懂.....不知道43期深圳能不能过啊
回复 使用道具 举报
楼主正解!
回复 使用道具 举报
我基入学测试也遇到这个题了,代码稍微比这个少一点,思想也不难理解(搞了差不多一个下午吧);分享了交流一下吧;
public class Test10 {
        /*
         * 10、 金额转换,阿拉伯数字转换成中国传统形式。 例如:101000001010 转换为 壹仟零壹拾亿零壹仟零壹拾圆整
         */                                                                                               
        public static void main(String[] args) {
                long value = 456789;//数值11111101000001010
                System.out.println(trans(value));
               
        }
        public static String trans(long value){
                if(String.valueOf(value).length()>17){//可以支持更大的位数只需要在unit数组中添加单位即可
                        return  "超出计算范围,请重新输入(小于17位为有限范围)。";
                }
                char[] chinses = new char[] { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌','玖' };
                //单位
                char[] unit = new char[] {' ', ' ', '拾', '佰', '仟','万'};
                // 接收到的数字转换成数字字符串
                StringBuilder sBuilderVal = new StringBuilder(String.valueOf(value));
                sBuilderVal = sBuilderVal.reverse();
                //存放返回结果
                StringBuilder reVal = new StringBuilder();
                int count = 1 ;
                //由于数值到亿的时候每次的单位变化就是在前一次单位加上亿的单位
                int num = 4 ;
                while(sBuilderVal!=null){
                        if(count>=4){
                                num++;
                        }
                        StringBuilder countVal = new StringBuilder();
                        StringBuilder tempVal = new StringBuilder();
                        if(sBuilderVal.length()<=num){
                                //如果串长度没有四位则取出所有字符
                                tempVal.append(sBuilderVal.substring(0, sBuilderVal.length()));
                                //表示已经取出所有字符,设置程序出口
                                sBuilderVal = null ;
                        }else{
                                //每次取出的位用于转换
                                tempVal.append(sBuilderVal.substring(0,num));
                                sBuilderVal = sBuilderVal.delete(0, num);
                        }
                        tempVal = tempVal.reverse();
                        int zeroCount = 0;
                        for(int i = 0 ; i<tempVal.length();i++){
                                int cVal = Integer.parseInt(String.valueOf(tempVal.charAt(i)));
                                //如果连续两个或两个以上的零则不添加到结果中
                                if(cVal==0 && zeroCount==0){
                                        countVal.append(chinses[cVal]);
                                        zeroCount++;
                                }else if(cVal!=0){
                                        //如果取出的数字不是连续的零则存储到结果中
                                        countVal.append(chinses[cVal]);
                                        countVal.append(unit[tempVal.length()-i]);
                                }
                        }
                        //设置单位
                        if(!countVal.toString().endsWith("零")){
                                switch(count){
                                case 1 :
                                        countVal.append("圆整");
                                        break ;
                                case 2 :
                                        countVal.append("万");
                                        break;
                                case 3 :
                                        countVal.append("亿");
                                        break ;
                                case 4 :
                                        countVal.append("兆");
                                        break;
                                }
                        }
                        count++;
                        reVal.insert(0, countVal);
                }
                return reVal.toString() ;
        }
}
回复 使用道具 举报
27ZJQ 来自手机 中级黑马 2014-5-27 13:57:07
11#
还没学到,不懂。
回复 使用道具 举报
GGdog 发表于 2014-5-27 11:52
你好,这是面试时候的笔试题还是被录取之后报道时候的笔试题目啊?

什么也不是,你看过张孝祥老师的面试宝典吗?
那里有一个“算法与编程”,这个就是最后一题,我习惯是先自己做,再看老师答案,但那个答案我有点失望,因为不符合现实中真正的转换规律

  1. public class RenMingBi {

  2.         /**
  3.          * @param args add by zxx ,Nov 29, 2008
  4.          */
  5.         private static final char[] data = new char[]{
  6.                         '零','壹','贰','叁','肆','伍','陆','柒','捌','玖'
  7.                 };
  8.         private static final char[] units = new char[]{
  9.                 '元','拾','佰','仟','万','拾','佰','仟','亿'
  10.         };
  11.         public static void main(String[] args) {
  12.                 // TODO Auto-generated method stub
  13.                 System.out.println(
  14.                                 convert(135689123));
  15.         }

  16.         public static String convert(int money)
  17.         {
  18.                 StringBuffer sbf = new StringBuffer();
  19.                 int unit = 0;
  20.                 while(money!=0)
  21.                 {
  22.                         sbf.insert(0,units[unit++]);
  23.                         int number = money%10;
  24.                         sbf.insert(0, data[number]);
  25.                         money /= 10;
  26.                 }

  27.                 return sbf.toString();
  28.         }
  29. }
复制代码
贴给你看一下,或许你有新的想法

回复 使用道具 举报
楼主的功力不错啊
回复 使用道具 举报
GGdog 中级黑马 2014-5-27 11:52:28
8#
你好,这是面试时候的笔试题还是被录取之后报道时候的笔试题目啊?
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马