面试题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