问题:输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到999。
解题思路:首先注意n没有规定范围,意味着n可以输入很大的值,那么这种情况下,无论时用整型还是长整型都会溢出。所以需要考虑大数问题。可以通过字符串来解决大数问题。因为数字最大是n位的,需要用一个n+1长度的字符串(字符串最后以为是结束符‘\0’),字符串中每个字符都是‘0’ ~ ‘9’之间的某一个字符,用来表示数字中的一个。当实际的数字不够n位的时候,在字符串的前半部分补0.具体做法:首先把字符串中的么一个数字初始化位‘0’,然后每一次为字符串表示的数字加1,再打印出来。
bool Increment(char *number)
{
bool isOverflow = false;
int carrybit = 0;
int len = strlen(number); //strlen()返回字符串长度,不包括最后结尾符‘\0’
for(int i = len-1; i>=0; i--)
{
int sum = number[i] - '0' + carrybit;
if(i == len-1)
sum++;
if(sum >= 10)
{
if(i == 0)
isOverflow = true;
else
{
sum -= 10;
carrybit = 1;
number[i] = '0' + sum;
}
}
else
{
number[i] = '0' + sum;
break;
}
}
return isOverflow;
}
void PrintNumber(char *number)
{
bool isBegin0 = true;
int len = strlen(number);
for(int i=0; i < len; i++)
{
if(isBegin0 && number[i] != '0')
isBegin0 = false;
if(!isBegin0)
{
printf("%c",number[i]);
}
}
printf("\t");
}
void Print1ToMax(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,就会发现n位所有十进制数其实就是n个从0到9的全排列。也就是说,我们把数字的每一位都从0到9排列一遍,就得到了所有的十进制数。只不过排在前面的0不打印出来罢了。
void Print1ToMaxRecur(char *number, int len, int idx)
{
if(idx == len-1)
{
PrintNumber(number);
return;
}
for(int i=0; i < 10; i++)
{
number[index+1] = i + '0';
Print1ToMaxRecur(number, len, idx+1);
}
}
void Print2ToMax(int n)
{
if(n <= 0)
return ;
char *number = new char[n+1];
number[n] = '\0';
for(int i=0; i < 10; i++)
{
number[0] = i + '0';
Print1ToMaxRecur(number, n, 0);
}
delete[] number;
}
PrintNumber实现如一种方法。