面試題12:輸入數字n,按順序打印出從1最大的n位十進制數。好比輸入3,則打印出一、二、3一直到最大的3位數即999。面試
凡是數字計算的,須要考慮大數場景,即溢出。數組
解決方案:改用字符串或字符數組來表達大數。bash
根據 ASCII 碼錶, 字符 '0'~'9' 都有對應的整數表示,從 '0' 到 '9' 加 1 遞增,所以有以下算術關係:app
字符和數字之間的轉換:charA - '0' = numOfCharAui
1 = '1' - '0'
2 = '2' - '0'
3 = '3' - '0'
···
9 = '9' - '0'
複製代碼
字符之間的減運算 <=> 整數之間的減運算。spa
'1' - '1' = 1 - 1 = 0
'9' - '8' = 9 - 8 = 1
複製代碼
建立一個 StringBuilder 來拼接字符。3d
for循環,從個位加1算起,注意循環的中間變量進位的保存和賦值。code
public static void print1ToMax(int n) {
if (n < 0) {
return;
}
StringBuilder numStr = new StringBuilder();
for (int i = 0; i < n; i++) {
numStr.append('0');
}
while (isIncreasing(numStr, n)) {
print(numStr);
}
}
private static void print(StringBuilder sb) {
int start = sb.length();
// 找到第一個不爲0的索引
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) != '0') {
start = i;
break;
}
}
// 若是全是0,就不會打印
if (start < sb.length()) {
System.out.print(sb.substring(start) + " ");
}
}
private static boolean isIncreasing(StringBuilder numStr, int n) {
int carry = 0;
for (int i = n - 1; i >= 0; i--) {
int singleNum = numStr.charAt(i) - '0' + carry;
if (i == n - 1) {
singleNum ++; //在個位上自增
}
if (singleNum == 10) { //1. 若是有進位,則將當前位置爲0,對更大的下一位加1
if (i == 0) { //若是已經到最大的那位還有進位,則說明已經溢出,退出整個打印流程
return false;
} else {
numStr.setCharAt(i, '0');
carry = 1;
}
} else { //2. 若是沒有進位,則退出當前這個 for 循環,執行打印
numStr.setCharAt(i, (char) (singleNum + '0'));
break;
}
}
return true;
}
複製代碼
暫無。cdn