输入整数n,按顺序打印出从1到最大的n位数


import com.google.common.base.Preconditions;

/**
 * 打印大数:
 *
 * 1)字符和整数(0~127)之间可以相互转换,ascii码表中维护着字符和整数之间的映射关系。
 *      char emptyChar = 0;      // emptyChar表示空字符
 *      char zeroChar = '0';     // zeroChar表示字符0
 *      int emptyCharIntValue = emptyChar;  // 空字符转换为整数的值为0    即:emptyCharIntValue==0
 *      int zeroCharIntValue = zeroChar;    // 字符0转换为整数的值为48    即:zeroCharIntValue==48
 *
 * 2)若n和m的取值为0~9之间的整数,则:
 *      1> 'n' - 'm' == (n-'0') - (m-'0') == n - m
 *      2> 'n' + 'm' == (n-'0') + (m-'0')
 *      3> 将数字形式转换为字符形式: n + '0' == 'n'
 *
 * 3)故可以使用字符串(字符数组)来表示大数,用字符间的运算来实现对大数的运算。
 *
 */
public class NumberAndChar {


    /**
     * 问题:输入整数n,按顺序打印出从1到最大的n位数。
     *
     * 注意:若n较大时,则最大的n位数是一个很大的数,这个大数无法用long类型表示。
     *
     * @param n
     */
    public static void print1ToMaxOfNDigits(int n) {

        Preconditions.checkArgument(n > 0);

        StringBuffer numberStr = new StringBuffer();

        for(int i = 0; i < n; i++){
            numberStr.append('0');
        }

        while(!increment4NumberStr(numberStr)){
            printNumberStr(numberStr);
        }
    }


    /**
     * 说明:
     *  1)将numberStr代表的数字进行+1操作。
     *  2)numberStr的初始值由numberStr.length个'0'字符组成。
     *  3)该数字是numberStr.length位数字,若该数字+1后变成了numberStr.length+1位,则表示发生了溢出。
     *
     * @param numberStr
     *
     * @return +1后是否发生了溢出
     *
     */
    public static boolean increment4NumberStr(StringBuffer numberStr) {

        boolean isOverflow = false;     // +1后是否发生了溢出。

        int carry = 0;                  // 前一位+1后产生的进位。

        int length = numberStr.length();    // 数字的位数

        /**
         * 将最低位+1
         *  若没有发生进位,则执行一次后就退出循环。
         *  若发生了进位, 则需要执行两次循环,然后退出。
         */
        for (int i = length - 1; i >= 0; i--) {

            int nSum = (numberStr.charAt(i) - '0') + carry; // 获取该位上的值

            if (i == length - 1) {  // 将最低位+1
                nSum++;
            }

            if (nSum < 10) {        // 将最低位+1后没有产生进位。

                numberStr.setCharAt(i, (char)('0' + nSum));
                break;

            } else {                // 将最低位+1后产生了进位,所以还需要再次进入循环来计算高位的值。

                if (i == 0) {       // 在最高位+1后产生了进位,也就是说本次的+1操作导致了溢出。
                    isOverflow = true;
                } else {
                    nSum -= 10;     // 因为发生了进位,故该位应该减10
                    carry = 1;      // 因为是+1导致的进位,故进位量为1
                    numberStr.setCharAt(i, (char) ('0' + nSum)); // 设置该位上的值
                }
            }
        }
        return isOverflow;
    }

    /**
     * 打印表示数字的字符串:
     *
     * 注意:打印时,去掉开头的0
     *
     * @param numberStr
     */
    public static void printNumberStr(StringBuffer numberStr) {

        boolean beginFlag = false;

        for (int i = 0; i < numberStr.length(); i++) {

            if (!beginFlag && numberStr.charAt(i) != '0') {
                beginFlag = true;
            }

            if (beginFlag) {
                System.out.print(numberStr.charAt(i));
            }
        }
    }


    public static void main(String[] args) {

        print1ToMaxOfNDigits(3);

    }
}

 

你可能感兴趣的:(算法)