面試題 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();
}