剑指offer 17题:打印从1到最大的n位数

题目:输入数字n,按照顺序打印出从1到最大的n位十进制数,比如输入3,打印出1,2,3一直到最大的三位数999。

边界问题

首先考虑边界问题,n是否是一个任意正数。如果n可以很大,那么int,long或者long long类型的数无法满足本题的要求,这就是一道大数问题了。
大数问题通常使用字符数组来解决超出类型范围这个问题。

/*创建一个元素都是'0'的字符数组*/
char* number = new char[n+1];
memset(number,'0',n);
number[n] = '\0';

打印结果

打印从1到最大n位数,如果是字符数组,那么当数比较小的时候前面的位数需要用0来补位。例如098,但是这不符合用户的读数习惯,因此打印时应该省略前面的0,只打印出来98。

void PrintNumber(char* number)
{
    //strlen返回有效长度,不包含最后的'\0'
    int nLen = strlen(number);
    bool isPre0 = true;

    for(int i=0;i<nLen;++i)
    {
        //判断何时开始打印以及如何打印
        if(isPre0 && number[i]!='0')
            isPre0 = false;
        if(!isPre0)
            printf("%c", number[i]);
    }
    printf("\t");
}

函数框架(伪代码)

void PrintMaxNDigit()
{
    ...
    while()
        PrintNumber;

    delete[] number;
}

如何实现将字符与指定的数比较

方法一:strcmp()函数,可以实现将字符数组与指定的字符比较,但是每打印一个数就需要比较一次,时间复杂度较高,为O(n).

方法二:发现当n位数为"999...9"时,加1才会进位,可以通过这个特点来判断是否得到最大的n位数。

使用非递归法实现从1加至n位最大数

bool IsOverflow(number)
{
    bool checkMax = false;
    //进位设为0
    int carry = 0;
    int nLen = strlen(number);
    for(int i=nLen-1;i>=0;i--)
    {
        int nDigitNum = numbers[i]-'0'+carry;
        if(i==nLen-1)
            nDigitNum++;
        if(nDigitNum>=10)
        {
            //当首位数大于9时,则到达n位数最大值
            if(i==0)
                chek = true;
            else{
            nDigitNum -= 10;
            carry = 1;
            }
        }
        //末尾数转化为字符存入number中
        else{
            number[i] = nDigitNum+'0'; 
            break;
        }
    }
    return check;
}
void PrintMaxNDigit()
{
    ...
    //若此处用if则只能打印一个数,无法实现多个数
    while(!IsOverflow(number))
        PrintNumber;

}

使用递归法从1加至n位最大数

把每一位数字从0至9全部排列一遍,即得到所有的数字

void PrintMaxNDigit(){
    //建立字符数组
    ...
    for(int i=0;i<=9;++i){
        number[0] = i+'0';
        Print1ToN(number, n, 0);
    }
    delete[] number;
}

Print1ToN(char* number, int length, int index)
{
    //递归终点,index达到n位数时停止递归
    if(index==length-1){
        PrintNumber(number);
        return;
    }
    for(int i=0;i<10;++i)
    {
        number[index+1]=i+'0'
        Print1ToN(number, length, index+1);
    }
}
全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务