题目如下:
- 题目:输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印1、2 、3一直到最大的3位数即999
我们一般想到的方法:直接输出
实现代码如下:
//题目:输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印1、2 、3一直到最大的3位数即999
#include<stdio.h>
#include<string.h>
void print(int num){
if(num<=0){
return ;
}
int maxNum=1;//保存要输出的最大的数
while(num>0){
maxNum*=10;
num--;
}
int num_print=1;//用来表示要打印的变量
//int index=0;//索引
//char str[maxNum*2];
while(num_print<maxNum-1){
//str[index++]=num_print;
printf("%d",num_print);
printf("、");
//str[index++]='、';
num_print++;
}
printf("%d",num_print);
//puts(str);
}
int main(void){
int num;
scanf("%d",&num);
print(num);
return 0;
}
运行结果如下:从结果可以看出,程序的运行时间为3.34秒。
上面的这种方法当输入的n很大的时候,我们求最大的n位数是不是用整型(int)或者长整型(long long)都会溢出?也就是说,我们需要考虑大数问题。要解决这个问题,方法:用字符串或者数组来表示大数是最好的了。
实现代码如下
//题目:输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印1、2 、3一直到最大的3位数即999
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//法二:为了避免很大的数,而导致一个int、long都无法表示的情况,我们选择用 字符串来表示要输出的数字
//此函数用来模拟 将字符表示的数字加 1 的过程
bool Increment(char * num){
bool isOverFlow=false;
//先将字符转化为数字,然后进行加 1 操作
int len=strlen(num);
for(int i=0;i<len;i++){
num[i]-='0';
}
//进行 加 1操作
num[len-1]++;//对最后一位进行加 1 操作
for(int i=len-1;i>=0;i--) {
if(num[i]>=10){
if(i==0){//如果i等于0时产生了进位,则说明已经全部输出完成。
isOverFlow=true;
num[i]--;
}
else{
num[i]-=10;
num[i-1]+=1;
}
}
else{//如果没有产生进位,就直接退出循环
break;
}
//然后将数字转化为字符
}
for(int i=0;i<len;i++){
num[i]+='0';
}
return isOverFlow;
}
//输出num表示的数字
void my_printf(char * num){
int i=0;
while(num[i]=='0'){
i++;
}
puts(num+i);
}
void printNum(int n){
if(n<=0){
return;
}
char *num=(char*)malloc((n+1)*sizeof(char));//为num分配 n+1 个字节大小的空间,前n个字节用来保存我们即将要输出的数字,最后一个字节用来存放 '\0'
if(num == NULL) //检查下内存是否分配成功
exit(EXIT_FAILURE);
memset(num,'0',n*sizeof(char)); //用 字符 '0'来初始化num的前 n个字节
num[n] ='\0';//用 字符 '\0' 来初始化num的最后一个字节
while(!Increment(num)){
my_printf(num);
}
delete []num;
}
int main(void){
int n;
scanf("%d",&n);
printNum(n);
return 0;
}
还有一种方法:把问题转换为数字排列的解法