题目:
输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。
思路:
由于未指定n的大小,当n特别大时,无论是整形(int)或者长整型(long)都会溢出。因此使用数组的方法来避开陷阱。
方法一为普通循环法,方法二为递归法。
package jianzhioffer;
public class MS17 {
public static void main(String[] args) {
int n = 2;
dayin(n);
printToMaxOfDigits(n);
}
//方法一 字符数组
public static void dayin(int n){
if (n<=0) {
System.out.println("无效输入!");
return;
}
char[] array = new char[n+1];
for (int i = 0; i <array.length-1 ; i++) {
array[i] = '0';
}
array[n] = '\n';
while (!incrementNumber(array)){
print(array);
}
}
public static boolean incrementNumber(char[] array){
int sum =0;
boolean isoverflow = false;//是否溢出
int jinwei = 0; //是否进位
for (int i = array.length-2; i >=0 ; i--) {
sum = array[i]-'0'+jinwei; //初始化sum
if (i==array.length-2){sum++;} //如果是最后一位sum加一
if (sum>=10){ //如果大于10 则需考虑循环完成或进位的情况
if (i==0) isoverflow=true; //表明循环结束,数组加到最大值
else {
jinwei = 1;
array[i] = '0';
}
}
else {//没有进位 修改array[i]即可
array[i] = (char) (sum+'0');
break;
}
}
return isoverflow;
}
//打印数字
private static void print(char[] number) {
boolean isBeginning0 = true;
int nLength = number.length;
for (int i = 0; i < nLength; ++i) {
if(isBeginning0 && number[i]!='0'){
isBeginning0 = false;
}
if(!isBeginning0){
System.out.print(number[i]);
}
}
System.out.println();
}
//方法二 递归
//就像我之前想的使用N层循环来实现赋值,但直接for循环没法写的。
// 但通过递归可以实现,主要就是用一个值index,确定在循环的第几层,最后一层进行打印,否则继续循环下去
//打印1到最大的n位数的主方法
public static void printToMaxOfDigits(int n){
if (n<=0) {
System.out.println("错误输入1");
return;
}
char[] array = new char[n];
for (int i = 0; i <n ; i++) {
array[i] = '0';
}
for (int i = 0; i <10 ; i++) {
array[0] = (char)(i+'0');
printToMaxOfNDigitsRecursively(array,n,0);
}
}
//利用递归实现1到最大的n位数的全排列
public static void printToMaxOfNDigitsRecursively(char[] number, int n, int index) {
if (index==n-1){
print(number);
return;
}
for (int i = 0; i <10 ; i++) {
number[index+1] = (char) (i+'0');
printToMaxOfNDigitsRecursively(number,n,index+1);
}
}
}