题目:输入数字n,按顺序打印出从1最大的的n位数十进制数。比如输入3,则打印出1,2,3一直到最大的3位数即999。
-
1、跳进面试官的陷进
这个题目看起来很简单。我们看到这个问题后,最容易想到的办法是求出最大的n位数,然后用一个循环从1开始逐个打印。于是我们很容易写出下面的代码:
public class Print1ToMaxOfNDigits {
// 方法一:没有考虑大数的问题,跳进了面试官的陷进
public void print1ToMaxOfNDigits_Method1(int n){
int number = 1;
int i = 0;
// 找出最大数 + 1 = number
while(i++ < n){
number *= 10; // number = 10 的n次方
}
// 打印
for (i = 1; i < number; i++) {
System.out.println(i);
}
}
// 测试
public static void main(String[] args) {
Print1ToMaxOfNDigits ptd = new Print1ToMaxOfNDigits();
ptd.print1ToMaxOfNDigits_Method1(100);
}
}
初看之下好像没有什么问题,但如果仔细分析这个问题,我们就能注意到面试官没有规定 n 的范围。当输入n很大的时候,我们求最大的n位数是不是用整型(int)或者长整型(long)都会溢出?也就是说我们需要考虑大数问题。这是面试官在这道题里设置的一个大陷阱。
-
2、在字符串上模拟数字加法的解法,绕过陷进才能拿到Offer
经过前面的分析,我们很自然的想到解决这个问题需要一个大数。最常用的也是最容易的用字符串或者数组表达大数。接下来我们用字符串和数组分别来解决大数问题。
我们需要做两件事情:
1、在字符串表达的数字上模拟加法;
2、把字符串表达的数字打印出来。需要注意的是当实际数字不够n位的时候,在字符串的前半部分补0,但是打印的时候,这些0不能打印出来。
- 字符串实现
public class Print1ToMaxOfNDigits {
// 方法二:在字符串上模拟数字加法的模式
public static void print1ToMaxOfNDigits_Method2(int n){
if(n <= 0){
return;