17-打印从1到最大的n位数
大约 2 分钟
输入数字n,按照顺序打印从1到最大的n位十进制数。比如n=3,则打印1到999
最容易想到的是根据n求出最大的值是多少,然后使用一个for循环即可打印出所有数字,不过如果n很大的话,会造成溢出,这道题的考点就在大数问题。 大数可以使用字符串去表示,突破固有类型的限制,从而可以解决大数问题。
第一种 字符串模拟加法
使用字符来模拟数字的加法。
public void printNumbers2(int n) {
char[] chs = new char[n];
for (int i = 0; i < n; i++) {
chs[i] = '0';
}
while (incNumber(chs)) { //持续递增,直到变成 999 这种的
System.err.println(String.valueOf(chs));
}
}
private boolean isMax(char[] chs) { // 假如字符全是9了,表示已经是最大值了
boolean isMax = true;
for (int i = 0; i < chs.length; i++) {
if(chs[i] != '9'){
isMax = false;
break;
}
}
return isMax;
}
private boolean incNumber(char[] chs) {
boolean isMax = isMax(chs);
if (isMax) {
return false;
}
for (int i = chs.length - 1; i >= 0; i--) {
char ch = chs[i];
if (ch == '9') { //假如这一位是9,说明需要进位,将该位置0,继续循环
chs[i] = '0';
}else{ //假如ch不是9,说明可以在这一位上直接加1即可。
chs[i] = (char) ((int) ch + 1);
break;
}
}
return true;
}
第二种 排列组合
打印数字相当于一个排列组合的问题,将所有组合按照顺序列出来即可。这种递归思路需要好好思考理解。
public void Print1ToMaxOfNDigits(int n) {
if (n < 1) {
return;
}
char[] number = new char[n];
for (int i = 0; i < number.length; i++) {
number[i] = '0';
}
for (int i = 0; i < 10; i++) { //这里是一切的开端,将number[0]按照循环置为 0 1 2 3 4 5 6 7 8 9
number[0] = Character.forDigit(i, 10);
recur(number, 0);
}
}
private void recur(char[] num, int index) {
if (index == num.length - 1) { //假如index超过了num.length,说明已经到末尾了,结束,打印该字符串即可。
printNumber(num);
return;
}
for (int i = 0; i < 10; i++) {
num[index + 1] = Character.forDigit(i, 10);//将index的下一位依次置为 0 1 2 3 4 5 6 7 8 9 ,然后递归处理
recur(num, index + 1);
}
}
//前导0不做处理 便于看结果
private void printNumber(char[] num) {
System.err.println(num);
}
比如对于n=3,那么执行过程是这样的:
- 0 0 0
- 0 0 1
- 0 0 2
- ...