题目:输入数字n,按顺序打印从1到最大的n位十进制数。
这是一个大数问题,n较大时会产生溢出,需要用字符串来表示数字。
方法1:将n位的字符串中每一个数字初始化为‘0’,然后每次为字符串表示的数字加一,再打印。需要两步,一在字符串表达的数字上模拟加法,二将字符串表达的数字打印出来。
什么时候停止+1?当+1时最高位产生进位,表示此时已经是最大n位数。
java实现:
public void print1ToMaxOfNDigits(int n) {
if(n<0)
return;
char[] number=new char[n];
//初始化
for(int i=0;i<n;i++) {
number[i]='0';
}
while(!increment(number)) {
printNumber(number);
}
}
//判断加一后最高位是否有进位
public boolean increment(char[] num) {
boolean isOverflow=false;
int nTakeOver=0; //进位
int length=num.length;
//从最低位开始加一,并判断是否有进位,最高位有进位表示溢出
for(int i=length-1;i>=0;i--) {
int nSum=num[i]-'0'+nTakeOver; //nSum当前位数加上进位的和
if(i==length-1) //初始最低位加一
nSum++;
//产生进位
if(nSum>=10) {
if(i==0)//进位是最高位
isOverflow=true;
else {
nSum-=10;
nTakeOver=1;
num[i]=(char) (nSum+'0');
}
}else {
num[i]=(char) (nSum+'0');
break; //不产生进位,,没有溢出,跳出循环
}
}
return isOverflow;
}
//打印用字符串表示的数字,把补位的0去掉,遇到第一个非0字符再打印
public void printNumber(char[] num) {
int i=0;
int size=num.length;
while(i<size&&num[i]=='0') { //找到第一个非0字符
i++;
}
if(i==size) return; //全0不打印
char[] printNum=Arrays.copyOfRange(num, i, size);
System.out.println(printNum);
}
方法2:n位所有十进制数就是n个从0到9的全排列,即数字的每一位都从0到9排列一遍。用递归求解,从第0位开始设置,直到设置了数字的最后一位。
public void print1ToMaxOfDigits2(int n) {
char[] number=new char[n];
Arrays.fill(number,'0');
printOrder(number,n,0);//index从0开始一直到最后一位都被赋值。结束递归
}
public void printOrder(char[]num,int length,int index) {
if(index==length) {
return;
}
for(int i=0;i<=9;i++) {
num[index]=(char) ('0'+i);
if(index==length-1) {
printNumber(num);
}
printOrder(num,length,index+1);
}
}