一个有趣的数字转换问题

题目描述:

7340405 => 七百三十四万零四百零五

一个蛮有趣的数字转换问题。

不太完美的思路

需要做两次转换:

  1. 数字1,2,3…转为文字
  2. 进位制的转换

所以一开始的思路,想通过map去实现这个转换,但是写着写着发现极其不优雅

private Map<Integer, String> numMap;
    private Map<Integer, String> nameMap;
    {
        numMap = new HashMap<>();
        numMap.put(0, "零");
        numMap.put(1, "一");
        numMap.put(2, "二");
        numMap.put(3, "三");
        numMap.put(4, "四");

        nameMap = new HashMap<>();
        nameMap.put(1, "");
        nameMap.put(2, "十");
        nameMap.put(3, "百");
        nameMap.put(4, "千");
    }

    public String switchNum(int num) {
        String result = "";
        int count = 1;
        // num % 10 num = num / 10
        while (num > 0) {
            int key = num % 10;
            String numValue = numMap.get(key);

            String s = key == 0 ? "" : nameMap.get(count);

            result = numValue + s + result;
            num = num / 10;
            count++;
        }

        // todo 消除连续零,只保留一个
        return result;
    }

刷牙时的灵光一现

如果用数组的话是不是就可以少写很多map中的put

public static final String ZERO_STR = "零";
    public static final String TEN_K = "万";
    public static final String[] num2NameArray = new String[]{ZERO_STR, "一", "二", "三", "四", "五", "六", "七", "八", "九"};
    public static final String[] bit2NameArray = new String[]{"", "十", "百", "千", "万", "十万", "百万", "千万", "亿"};

    public String switchNum(int num) {
        String result = "";
        int bitCount = 0;
        while (num > 0) {
            int value = num % 10;

            // 获取数字对应的文字
            String numName = num2NameArray[value];

            // 如果某一位上是0,就不用带上进位,比如101, 十位上就只是零;否则带上进位
            String bitName = value == 0 ? bit2NameArray[0] : bit2NameArray[bitCount];

            // 一串文字中应该只有一个万:111_111 十一万一千一百一十一,而不是 一十万一万一百一十一
            String numAndBit = numName + bitName;
            if (numAndBit.contains(TEN_K) && result.contains(TEN_K)) {
                numAndBit = numAndBit.replace(TEN_K, "");
            }

            // 处理连续多个零的情况,比如 1007,应该为 一千零七,而不是 零零七
            boolean continuousZeros = (numName + bitName).equals(ZERO_STR) && result.startsWith(ZERO_STR);
            result = continuousZeros ? result : numAndBit + result;

            num = num / 10;
            bitCount++;
        }

        // 最后处理一个习惯上的问题:11 读 十一,而不读 一十一
        if (result.startsWith("一十")){
            return result.substring(1);
        }
        return result;
    }

    public static void main(String[] args) {
        TestDemo testDemo = new TestDemo();
        System.out.println(testDemo.switchNum(7340405));
    }

测试一

一个有趣的数字转换问题_开发语言

测试二

一个有趣的数字转换问题_开发语言_02

测试三

一个有趣的数字转换问题_开发语言_03