《剑指Offer》面试题12:打印1到最大的n位数

题目如下:

  • 题目:输入数字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;
} 

还有一种方法:把问题转换为数字排列的解法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值