将阿拉伯数字转化成汉字

题目描述

将阿拉伯数字转换成汉字表示的形式,如 175020060,表示为:"一亿七千五百零二万零六十"。

解题思路

  • 将汉字数值和单位分别存储在 numArrays 和 units 这两个数组中,并利用全局变量 ans 存储解析的结果。我们首先以简单的数字为例,如 num = 4021。依次从高位到低位获取数值,num 的长度 n = 4,所以我们对 num 除、膜 1000,分别得到 div = 4 以及 mod = 21。div 为 num 最高位的值,mod 为剩余部分的数值。然后我们在 ans 中添加 "四" 和单位 "千",可以发现此时 21 的长度小于 n - 1,因为 num 中间存在数字 0,因此需要在结果中添加 "零"。然后我们判断 mod 是否为 0,若不为 0 则继续递归,如果数值长度减小到 1,则直接添加对应的数字。
  • 当数值达到几十万或者上亿时,上述方法并不适用,因为万之后的单位不是连续的,如果我们添加 "十万、百万" 这些连续单位后,上述方法会将 544021 解析为:"五十万四万四千零二十一",注意多了一个万。解决方法:以 "万" 和 "亿" 为分割点对数值进行拆分,当高位数值解析完成后我们在结果中添加单位 "万" 或 "亿",然后解析低位数值,注意如果高位数值的最后一位为 0,或者低位数值以 0 开头,我们都需要在结果中添加 "零"。

代码实现

Java 代码如下:

public class NumberConvert {

  private static final char[] numArrays = {'零', '一', '二', '三', '四', '五', '六', '七', '八', '九'};
  private static final char[] units = {'十', '百', '千', '万', '亿'};
  private static final StringBuilder ans = new StringBuilder();

  /**
   * 采用递归的方法将转换的结果存储到 ans 变量中, 注意 `万` 和 `亿` 在 units 数组中不是连续的, 所以
   * 当数字达到5位数或9位数时, 我们分开讨论。
   *
   * @param num
   */
  private static void intToChineseNum(int num) {
      String s = String.valueOf(num);
      char[] chars = s.toCharArray();
      int n = chars.length;

      // 只剩下一位时, 直接返回 numArrays 数组中对应的数字
      if (n == 1) {
          ans.append(numArrays[chars[0] - '0']);
          // 如果 num 超过 5 位, 则先判断是否上亿, 然后将 num 拆分
      } else if (n >= 5) {
          n = n >= 9 ? 9 : 5;
          int multi = (int) Math.pow(10, n - 1);
          // div 表示 num 中上亿或上万的部分数值
          int div = num / multi;
          // mod 表示剩余的部分数值
          int mod = num % multi;
          // 对前一部分数值进行转换, 然后添加单位万/亿
          intToChineseNum(div);
          ans.append(n == 5 ? units[3] : units[4]);
          String s1 = String.valueOf(div);
          String s2 = String.valueOf(mod);
          // 判断中间是否有 0
          if (s.charAt(s1.length() - 1) == '0' || s2.length() < n - 1) ans.append("零");
          // 转换剩余部分
          intToChineseNum(mod);
          // 如果 num 不超过 5 位, 处理过程与上面相似
      } else {
          int multi = (int) Math.pow(10, n - 1);
          int div = num / multi;
          int mod = num % multi;
          ans.append(numArrays[div]).append(units[n - 2]);
          if (mod != 0) {
              if (String.valueOf(mod).length() < n - 1) {
                  ans.append("零");
              }
              intToChineseNum(mod);
          }
      }
  }

  public static void main(String[] args) {
      intToChineseNum(175020060);
      System.out.println(ans.toString());
  }
}
  • 输出
    一亿七千五百零二万零六十

待改进

  • 对于大数的解析我们采用了拆分数值的方式,或许有更加便捷高效的方法。
  • 整数 11 会被解析为 "一十一",不符合日常习惯。
  • 能够解析的范围最高到亿,再大的范围会出现 Bug。

欢迎批评指正!!!


John同学来学习
3 声望1 粉丝

萌新程序员,闲暇之余记录一下近期的学习内容,期待能够每天进步一点点୧☉□☉୨