黑马程序员技术交流社区

标题: 金钱转换 [打印本页]

作者: 王建亮    时间: 2015-6-23 21:01
标题: 金钱转换
本帖最后由 王建亮 于 2015-6-23 21:22 编辑
  1. package com.itheima;

  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;

  5. /**
  6. * 题目: 金额转换,阿拉伯数字转换成中国传统形式。 例如:101000001010 转换为 壹仟零壹拾亿零壹仟零壹拾圆整
  7. *
  8. * 思路: 将阿拉伯数字从最低位开始每四个数字为一组进行分组,然后通过一系列的运算以此在每一位后面加上正确的单位 每一组的后面再加上如 "圆整", "万",
  9. * "亿", "兆" 这样的单位,最后将这些结果拼成到一个StringBuilder中 再对一些小的细节进行正则表达式的替换,最终打印正确的中国传统形式。
  10. * 注:不考虑小数部分
  11. *
  12. * @author wjl
  13. *
  14. */
  15. public class Test10 {
  16.         public static void main(String[] args) {
  17.                 // 定义一个输入流来读取从控制台输入的阿拉伯数字
  18.                 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  19.                 String source = null;// 定义一个String变量来接受从控制台读取的数据
  20.                 try {
  21.                         System.out.print("请输入合法的阿拉伯数字:");
  22.                         // 使用while循环可以无限输入进行转换,当输入over的时候停止工作(无视大小写)
  23.                         while (!"over".equalsIgnoreCase(source = in.readLine())) {
  24.                                 // 对source的合法性校验
  25.                                 // 必须是数字,不能是0开头,长度是1-16位
  26.                                 // 声明一个正则表达式
  27.                                 String moneyReg = "[1-9][0-9]{0,15}";
  28.                                 if (!source.matches(moneyReg)) {// 如果校验未通过
  29.                                         System.out.println("您输入了非法的数字。");

  30.                                 } else {
  31.                                         System.out.println(source + "对应的中国传统形式是:"
  32.                                                         + changeMoneyToChinese(source));
  33.                                 }
  34.                                 System.out.print("请输入合法的阿拉伯数字:");
  35.                         }
  36.                 } catch (IOException e) {
  37.                         System.out.println("系统故障。。");
  38.                 } finally {
  39.                         // 关闭流对象
  40.                         try {
  41.                                 in.close();
  42.                         } catch (IOException e) {
  43.                                 // TODO Auto-generated catch block
  44.                                 e.printStackTrace();
  45.                         }
  46.                 }
  47.         }

  48.         /**
  49.          * @param source
  50.          *            一个小于16位的阿拉伯数字形式的字符串
  51.          * @return 返回中国传统形式
  52.          */
  53.         public static String changeMoneyToChinese(String source) {
  54.                 // 定义一个汉语的0到9的数组
  55.                 String[] num = new String[] { "零", "壹", "貳", "叁", "肆", "伍", "陆", "柒",
  56.                                 "捌", "玖" };
  57.                 // 定义一个在每四位中会用到的单位
  58.                 String[] unit = new String[] { "拾", "佰", "仟" };
  59.                 // 定义一个在每组的后缀单位
  60.                 String[] bigUnit = new String[] { "圆整", "万", "亿", "兆" };
  61.                 // 最终结果,使用StringBuilder
  62.                 StringBuilder result = new StringBuilder("");
  63.                 // 每组的后缀单位bigUnit的当前下标值
  64.                 int nowBigUnit = 0;
  65.                 // 对源数据进行for循环
  66.                 for (int i = source.length(); i >= 0; i -= 4) {
  67.                         // 从最低位开始每4位为一组,剩下的不足4个的为一组
  68.                         String money = source.substring(i < 4 ? 0 : i - 4, i);
  69.                         // 对四位进行处理
  70.                         StringBuilder sb = new StringBuilder();
  71.                         // 每一位的后缀单位unit的当前下标值,默认为-1
  72.                         int nowUnit = -1;
  73.                         // 对获取到的每组四位数字通过for循环进行转换
  74.                         for (int index = money.length() - 1; index >= 0; index--) {
  75.                                 // 因为unit只有三个单位,每组的最低位暂时不需要单位
  76.                                 if (index != money.length() - 1)
  77.                                         nowUnit++;
  78.                                 // 获取遍历到的单个字符
  79.                                 char ch = money.charAt(index);
  80.                                 if (ch != '0') {// 如果该字符不是0
  81.                                         // 防止第一位就是一个非零的情况,如果是其他位就获取相对应的单位
  82.                                         if (index != money.length() - 1)
  83.                                                 sb.insert(0, unit[nowUnit]);
  84.                                         // 再将对应的中文插入StringBuilder的第一位
  85.                                         sb.insert(0, num[Integer.parseInt(ch + "")]);
  86.                                 } else {// 当ch为0的时候
  87.                                         // 声明一个char来存储在该循环中前一个字符
  88.                                         char preCh = ' ';
  89.                                         if (index <= money.length() - 2) {
  90.                                                 preCh = money.charAt(index + 1);
  91.                                         }
  92.                                         if (preCh == '0') {// 如果前一个也是0那么只需要存储一个零就好了,然后接着走for循环
  93.                                                 continue;
  94.                                         } else {// 如果仅仅是该位为0就插入零
  95.                                                 sb.insert(0, num[Integer.parseInt(ch + "")]);
  96.                                         }
  97.                                 }
  98.                         }
  99.                         // 如果sb的值是以零结尾的,同时sb的值并不是零,那么就将最后位的零删除
  100.                         if (sb.toString().endsWith("零")) {
  101.                                 if (!sb.toString().equals("零")) {
  102.                                         sb.delete(sb.length() - 1, sb.length());
  103.                                 }
  104.                         }
  105.                         // 如果通过上面的操作得到的是一个长度大于0,并且值不为零的StringBuilder,就在该组的后面接上后缀单位
  106.                         if (sb.length() > 0 && !sb.toString().equals("零")) {
  107.                                 sb.append(bigUnit[nowBigUnit]);
  108.                         }
  109.                         // 不管情况如何,每组的后缀单位必须要加一
  110.                         nowBigUnit++;
  111.                         // 将每组的最终结果拼接到代表程序最终结果的result StringBuilder类型
  112.                         result.insert(0, sb);
  113.                 }
  114.                 // 如果最终结果是以 多个零结尾 则替换成 空 然后将中间部位的多个零替换成一个零就可以得到中国传统形式了
  115.                return result.toString().replaceAll("零+$", "").replaceAll("零+", "零");
  116.         }

  117. }
复制代码







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