面试题12:
题目:输入数字n,按照顺序答应出从1最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的三位数即999。
对于这道题进行时,咱们会进行一些分析,当你输入3时,最大的三位数是999,这就是说这个最大的数是9*10^n-1+9 *10^n-2+。。。+9 *10^0。所以在这我想学习C语言的初学者都可以打出下面这个程序:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
void print_number(int n)
{
int number = 1;
int i = 0;
while (i++<n)
{
number *= 10;
}
for (i = 1; i < number; i++)
{
printf("%d\n", i);
}
}
int main()
{
int n = 0;
printf("请输入n:");
scanf("%d", &n);
print_number(n);
system("pause");
return 0;
}
在这里我们我们就可以知道你所打印的最大数其实就是你的10^n-1。上述方法看似解决了这个问题,但是,还是以前的问题,咱们应该考虑一些边界因素和一些其他的因素,让代码做到最好。其实在这你就要想了,int的返回最大也就是2的32次方-1,所以,对于一个很大的数,这个程序是无法显示的。所以我们在这里要考虑大数的问题,在这里请你谨记,处理大数最容易也是最常用的方法就是字符串或者数组来表示。仔细想一想是不是这个道理呢,字符串可以放下无比庞大的数。接下来的问题,就是如何用字符串或者数组来表示呢?这也是在面试时考察你的一点,我想你很容易就能想到对于数字0-9,我们就使用字符‘0’-‘9’来表示。在这个表示的过程中,我们要注意字符串的NUL结束位,所以对一个含有n位的字符串,我们需要一个长度为n+1的字符串。当实际数字不够n位时,在字符串前半部分补0;这样我们先把字符串每一个数字初始化为‘0’,然后每次给字符加1,再打印,这样就可以了。
所以接下来我们可以写出更好的一种方法:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int Increment(char *num)
{
int isOverflow = 0;
int len = strlen(num);
int i;
for (i = 0; i<len; i++)
num[i] = num[i] - '0';
num[len - 1]++;
for (i = len - 1; i >= 0; i--)
{
if (num[i] >= 10)
{
if (i == 0)
{
isOverflow = 1;
num[i]--;
}
else
{
num[i] -= 10;
num[i - 1] += 1;
}
}
else
break;
}
for (i = 0; i<len; i++)
num[i] = num[i] + '0';
return isOverflow;
}
void Print_n(int n)
{
if (n <= 0)
return;
char *num = (char *)malloc((n + 1)*sizeof(char));
if (num == NULL)
exit(EXIT_FAILURE);
memset(num, '0', n*sizeof(char));
num[n] = '\0';
while (!Increment(num))
{
int i = 0;
while (num[i] == '0')
i++;
printf("%s\n", num + i);
}
free(num);
num = NULL;
}
int main()
{
int n;
printf("请输入n:");
scanf("%d", &n);
Print_n(n);
system("pause");
return 0;
}