当我们看到这道题的时候,我们会首先想到找到最大的n位数,然后从1开始逐个打印;也就是下边的代码:
void printonetomax1(int n)
{
int num = 1;
int i = 0;
for (i = 0; i < n; i++)
{
num = num * 10;
}
for (i = 1; i <= num; i++)
{
printf("%4d", i);
}
}
这种代码在n不是很大的时候才能运行,所以这种代码不是我们给面试官的代码。
所以我们用到字符串模拟数字加法的解法,绕过陷阱(n的范围)。
字符串模拟数字加法
首先我们需要一个长度为n+1的字符串,最后一个字符为'\0',把字符串中其他字符初始化成'0',然后每一次对字符串+1,再打印。
所以,我们的核心就只有两件事:(1)字符串+1;(2)打印。
(1)字符串+1
int charaddone(char* num)
{
int ret=0;
int length = strlen(num);
int carry = 0;//进位
int i;
int sum;
for (i = length - 1; i >= 0; i--)
{
sum = num[i] - '0' + carry;//第i位上的数
if (i == length - 1)
sum++;
if (sum >= 10)//有一个数位满10了
{
if (i == 0)//当是第一位满10时,证明已经到最大的n位数了
ret = 1;
else//满10进1
{
sum = sum - 10;
carry = 1;
num[i] = sum + '0';
}
}
else
{
num[i] = '0' + sum;
break;
}
}
return ret;
}
void printonetomax(int n)
{
int i;
if (n <= 0)
return;
char* num = malloc(n + 1);
for (i = 0; i < n; i++)
num[i] = '0';
num[n] = '\0';
while (charaddone(num)==0)//字符串+1
{
printnum(num);//打印
}
}
(2)打印
经过步骤(1)后,生成的字符串(假设n=4)都是'000x'、'00xx'、'0xxx'、'xxxx',我们打印的时候只能打印非0字符。
void printnum(char* num)
{
int judge = 1;//判断是不是到第一个非0的数
int length = strlen(num);
int i;
for(i = 0; i < length; i++)
{
if (num[i] != '0'&&judge == 1 )
{
judge = 0;
}
if (judge == 0)
printf("%c", num[i]);
}
}