跳至主要內容

17-打印从1到最大的n位数

daipeng大约 2 分钟

输入数字n,按照顺序打印从1到最大的n位十进制数。比如n=3,则打印1到999

最容易想到的是根据n求出最大的值是多少,然后使用一个for循环即可打印出所有数字,不过如果n很大的话,会造成溢出,这道题的考点就在大数问题。 大数可以使用字符串去表示,突破固有类型的限制,从而可以解决大数问题。

第一种 字符串模拟加法

使用字符来模拟数字的加法。

public void printNumbers2(int n) {
        char[] chs = new char[n];
        for (int i = 0; i < n; i++) {
            chs[i] = '0';
        }
        while (incNumber(chs)) { //持续递增,直到变成 999 这种的
            System.err.println(String.valueOf(chs));
        }
    }
   
    private boolean isMax(char[] chs) { // 假如字符全是9了,表示已经是最大值了
        boolean isMax = true;
        for (int i = 0; i < chs.length; i++) {
            if(chs[i] != '9'){
                isMax = false;
                break;
            }
        }
        return isMax;
    }

    private boolean incNumber(char[] chs) {
        boolean isMax = isMax(chs);
        if (isMax) {
            return false;
        }
        for (int i = chs.length - 1; i >= 0; i--) { 
            char ch = chs[i];
            if (ch == '9') { //假如这一位是9,说明需要进位,将该位置0,继续循环
                chs[i] = '0';
            }else{ //假如ch不是9,说明可以在这一位上直接加1即可。
                chs[i] = (char) ((int) ch + 1);
                break;
            }
        }
        return true;
    }

第二种 排列组合

打印数字相当于一个排列组合的问题,将所有组合按照顺序列出来即可。这种递归思路需要好好思考理解。

public void Print1ToMaxOfNDigits(int n) {
        if (n < 1) {
            return;
        }
        char[] number = new char[n];
        for (int i = 0; i < number.length; i++) {
            number[i] = '0';
        }
        for (int i = 0; i < 10; i++) { //这里是一切的开端,将number[0]按照循环置为 0 1 2 3 4 5 6 7 8 9
            number[0] = Character.forDigit(i, 10);
            recur(number, 0);
        }
    }
    private void recur(char[] num, int index) {
        if (index == num.length - 1) { //假如index超过了num.length,说明已经到末尾了,结束,打印该字符串即可。
            printNumber(num);
            return;
        }
        for (int i = 0; i < 10; i++) {
            num[index + 1] = Character.forDigit(i, 10);//将index的下一位依次置为 0 1 2 3 4 5 6 7 8 9 ,然后递归处理
            recur(num, index + 1);
        }
    }
  //前导0不做处理 便于看结果
    private void printNumber(char[] num) {
        System.err.println(num);
    }

比如对于n=3,那么执行过程是这样的:

  1. 0 0 0
  2. 0 0 1
  3. 0 0 2
  4. ...