面试题12:打印1到最大的n位数
题目:输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999.
解法1:解决大数常用的方法是用字符串或者数组表达大数。当字符串表达数字的时候,最直观的方法就是字符串里每个字符都是‘0’ 到 ‘9’ 之间的某个字符,用来表示数字中的一位。因为数字最大是n位的,因此我们需要一个长度为n+1的字符串(字符串中最后一个是结束符号‘\0’)。当实际数字不够n位的时候,在字符串的前半部分补0。
void Print1ToMaxOfNDigits(int n){
if(n <= 0)
return;
char *number = new char[n + 1];
memset(number, '0', n);
number[n] = '\0';
while(!Increment(number)){
PrintNumber(number);
}
delete []number;
}首先把字符串中的每一个数字都初始化为‘0’,然后在字符串表达的基础上模拟加法,再把合法的字符串数字打印。(比较字符串大小可用strcmp,时间复杂度为O(n))
bool Increment(char *number){
bool isOverflow = false;
int nTakeOver = 0;
int nLength = strlen(number);
for(int i = nLength - 1; i >= 0; i--){
int nSum = number[i] - '0' + nTakeOver;
if(i == nLength - 1)
nSum ++;
if(nSum >= 10){
if(i == 0)
isOverflow = true;
else{
nSum -= 10;
nTakeOver = 1;
number[i] = '0' + nSum;
}
}else{
number[i] = '0' + nSum;
break;
}
}
return isOverflow;
}PrintNumber函数打印符合我们阅读习惯的数字
void PrintNumber(char *number){
bool isBeginning0 = true;
int nLength = strlen(number);
for(int i = 0; i < nLength; ++i){
if(isBeginning0 && number[i] != '0')
isBeginning0 = false;
if(!isBeginning0){
printf("%c", number[i]);
}
}
printf("\t");
}
解法2:全排列递归
void Print1ToMaxOfNDigits(int n){
if(n <= 0)
return ;
char *number = new char[n + 1];
number[n] = '\0';
for(int i = 0; i < 10; ++i){
nnumber[0] = i + '0';
Print1ToMaxOfNDigitsRecursively(number, n, 0);
}
delete[] number;
}
void Print1ToMaxOfNDigitsRecursively(char *number, int length, int index){
if(index == length - 1){
PrintNumber(number);
return;
}
for(int i = 0; i < 10; ++i){
number[index + 1] = i + '0';
Print1ToMaxOfNDigitsRecursively(number, length, index + 1);
}
}
测试用例:(1)功能测试(输入1、2、3等)
(2)特殊输入测试(输入-1、0)
如果面试题是关于n位的整数并且没有限定n的取值范围,或者是输入任意大小的整数,那么这个题目很有可能是需要考虑大数问题的。字符串是一个简单、有效的表示大数的方法。
本文介绍了一种打印从1到最大的n位数的方法,包括使用字符串模拟加法和全排列递归两种解法,并提供了详细的代码实现。

被折叠的 条评论
为什么被折叠?



