The sword refers to the second edition of the offer interview question 17: print 1 to the largest n digits (java)

Title description:
Input the number n, and print out the decimal numbers from 1 to the largest n digits in order. For example, if you enter 3, it will print out 1, 2, 3 until the largest 3 digits, that is, 999.

Jump into the interviewer's trap:
This question seems easy. After we saw this problem, the easiest way to think of is to find the largest n digits, and then use a loop to print one by one starting from 1. So we can easily write the following code.

public static void print1ToMaxOfNDigits(int n) {
        int number = (int) Math.pow(10, n);
        for (int i = 1; i < number; ++i)
            System.out.println(i);
    }

At first glance there is no problem, but if we analyze the question carefully, we can notice that the interviewer did not specify the range of n. When the input n is very large, will we use an integer (int) or a long integer (long) to find the largest n-digit number and overflow? That is to say, we need to consider the problem of large numbers. This is a big trap set by the interviewer in this question.

Simulate the solution of digital addition on the array, and get the offer by bypassing the trap:
After the previous analysis, we naturally thought that a large number is needed to solve this problem. The most common and easiest way to express large numbers is to use strings or arrays. Next we use arrays to solve large number problems.
code show as below:

/**
 * 打印从1到最大的n位数:使用数组表示大数
 */
public class PrintOneToMaxNthDigits1 {

    // 使用数组实现对数进行+1操作
    public static boolean increment(int[] number) {
        // 最高位产生进位标志
        boolean isOverFlow = false;

        // 进位位
        int carry = 0;

        for (int i = number.length - 1; i >= 0; i--) {
            int sum = number[i] + carry;
            if (i == number.length - 1) {
                sum++;
            }
            if(sum >= 10){
                if(i == 0)
                    isOverFlow = true;
                else{
                    sum = sum - 10;
                    carry = 1;
                    number[i] = sum;
                }
            }else{
                number[i]++;
                break;
            }
        }
        return isOverFlow;
    }

    // 打印数组中表示的数,如果数组中表示的数字位数小于n,则不打印前面的0
    public static void print(int[] number) {
        // 标记:判断是否可以开始打印
        boolean isBeginning = false;
        for (int i = 0; i < number.length; i++) {
            if (!isBeginning && number[i] != 0) {
                isBeginning = true;
            }
            if (isBeginning)
                System.out.print(number[i]);
        }
        System.out.println();
    }

    public static void main(String[] args) {
        //使用数组来模拟大数
        int[] number = new int[3];
        while(!increment(number)){
            print(number);
        }
    }
}

Increment should pay attention to the termination condition
Print function: pay attention to processing the preceding '0' character

Convert the problem into a numerical arrangement solution, recursion makes the code more concise:
use the method of number arrangement: if we add 0 in front of the number, we will find that all n-digit decimal numbers are actually n full permutations from 0 to 9 . That is, we get all the decimal numbers by arranging each digit of the number from 0 to 9. Of course, when printing, we should remove the preceding 0-fill.
code show as below:

/**
 * 打印从1到n位的最大数:使用递归实现全排列
 */
public class PrintOneToMaxNthDigits2 {

    //打印数
    public void printNumber(StringBuffer sb){
        boolean flag = false;

        for(int i = 0; i < sb.length(); i++){
            if(!flag && sb.charAt(i) != '0'){
                flag = true;
            }
            if(flag){
                System.out.print(sb.charAt(i));
            }
        }
        if(flag)
            System.out.println();
    }

    //打印从1到n位的最大数
    public void Print1ToMaxOfNDigits(int n){
        if(n <= 0)
            return ;

        //初始化数字(用StringBuffer表示)
        StringBuffer sb = new StringBuffer(n);
        for(int i = 0; i < n; i++){
            sb.append('0');
        }

        print1ToMaxOfNDigits_Recursely(sb, n, 0);
    }

    public void print1ToMaxOfNDigits_Recursely(StringBuffer sb, int n, int index){
        if(index == n){
            printNumber(sb);
            return ;
        }

        for(int i = 0; i < 10; i++){
            sb.setCharAt(index, (char)(i+'0'));
            print1ToMaxOfNDigits_Recursely(sb, n, index+1);
        }
    }

    public static void main(String[] args) {
        PrintOneToMaxNthDigits2 test = new PrintOneToMaxNthDigits2();
        test.Print1ToMaxOfNDigits(3);
    }

}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325609028&siteId=291194637