剑指Offer——题17(打印从 1 到最大的 n 位数)

【题目】:

输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。

【思路】:

解决这个问题的关键是大数问题。最常用的方法是用字符串或字符数组表达大数。

针对本题,需要解决的问题是在字符串或字符数组表达的大数中模拟加法、打印大数。

package com.offer.offer17;

/**
 * @author zth
 * @Date 2019-08-10 8:21
 */
public class Print1ToMaxOfNDigits {
    public void print1ToMaxOfNDigits(int n){
        if (n<=0){
            return;
        }
        char[] number = new char[n];
        // 初始化为 0
        for (int i = 0; i < number.length; i++) {
            number[i] = '0';
        }

        while (!increment(number)){
            printNumber(number);
        }
    }

    /**
     * 进行加一操作,
     * @param number 对 number 加一
     * @return 达到最大值后返回 true,否则返回 false
     */
    int nSum = 0;
    private boolean increment(char[] number){
        int nTakeOver = 0;
        for (int i = number.length-1; i >=0 ; i--) {
            // 当前位置数字
            nSum = (number[i]-'0')+nTakeOver;
            // 最低为加一
            if (i == number.length-1) nSum++;
            // 有进位
            if (nSum >= 10){
                // 如果当前位为最高位,则停止
                if (i==0){
                    return true;
                }else {
                    nSum -= 10;
                    nTakeOver = 1;
                    number[i] = (char)('0'+nSum);
                }
            }else {
                number[i] = (char)('0'+nSum);
                // 没有进位,在当前位结束
                break;
            }
        }
        return false;
    }

    /**
     * @param number 打印 number 字符数组对应的数字
     */
    void printNumber(char[] number){
        // 从第一个非 0 开始打印
        boolean isBeginner0 = true;
        for (int i = 0; i < number.length; i++) {
            if (isBeginner0 && (number[i]-'0') !=0){
                isBeginner0 = false;
            }
            if (!isBeginner0){
                System.out.print(number[i]);
            }
        }
        System.out.println();
    }

    // ========测试代码=============
    void test(int nDigits) {
        System.out.println("===test begin===");
        print1ToMaxOfNDigits(nDigits);
        System.out.println("===test over===");
    }

    public static void main(String[] args) {
        Print1ToMaxOfNDigits demo = new Print1ToMaxOfNDigits();
        demo.test(-1);
        demo.test(0);
        demo.test(1);
        demo.test(2);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值