面试题 12:打印1到最大的n位数
题目
输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。
分析
如果不作分析,可能直接就会采用:算出n位数的最大值,然后循环输出就完事儿了。但这个题显然不是这么简单,题目中没有给n做任何限定,如果n的值很大,那么不管是double还是long类型都无法承担存储大数的责任。
在java中处理大数大概有三种方案:
- 使用String模拟大数,需要自己实现加法操作。
- 使用数组模拟大数,也需要自己实现加法操作。
- 使用BigDecimal。
本例中,使用int数组来模拟大数操作。
解:java
public static void main(String args[]) {
printToMaxNDigits(2);
}
public static void printToMaxNDigits(int n) {
if (n <= 0) { // 输入边界检查,防止-1、0之类的非法输入
return;
}
int[] number = new int[n];
while(increment(number)) { // increment的作用是 + 1,+ 1成功返回true,去打印否则结束循环
printNumber(number);
}
}
private static boolean increment(int[] number) {
if (number == null || number.length == 0) { // 可能出现的边界检查
throw new IllegalArgumentException("number is empty");
}
for (int i = number.length - 1; i >= 0; i--) { // 模拟加法操作,从低位到高位遍历
if (number[i] < 9) { // 0~8 原地 +1
number[i] += 1;
return true;
} else { // 9置零,下次循环是将高位进1
number[i] = 0;
}
}
return false;
}
// 直接打印数组将出现[0, 0, 1]这种情况,高位为0不符合阅读习惯,需要自己实现打印函数
private static void printNumber(int[] number) {
if (number == null || number.length == 0) { // 可能出现的边界检查
throw new IllegalArgumentException("number is empty");
}
boolean hasPrint = false;
for (int i = 0; i < number.length; i++) { // 从高位向低位遍历
if (number[i] != 0 || hasPrint) { // 当遇到第一个不为零时开始打印
hasPrint = true;
System.out.print(number[i]);
}
}
System.out.println();
}