zoukankan      html  css  js  c++  java
  • 《剑指offer》第十七题:打印1到最大的n位数

    // 面试题17:打印1到最大的n位数
    // 题目:输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则
    // 打印出1、2、3一直到最大的3位数即999。
    
    #include <cstdio>
    #include <memory>
    
    void PrintNumber(char* number);
    bool Increment(char* number);
    void Print1ToMaxOfNDigitsRecursively(char* number, int length, int index);
    
    // ====================方法一====================
    //字符串模拟加法进位
    void Print1ToMaxOfNDigits_1(int n)
    {
        if (n <= 0)
            return;
    
        char* number = new char[n + 1];
        memset(number, '0', n);
        number[n] = '';
    
        while (!Increment(number)) //字符串加法
        {
            PrintNumber(number);
        }
        delete[] number;
    }
    
    // 字符串number表示一个数字,在 number上增加1
    // 如果做加法溢出,则返回true;否则为false
    bool Increment(char* number)
    {
        bool isOverFlow = false; //溢出标志
        int nTakeOver = 0; //进位标志
        int length = strlen(number);
    
        //从尾到头检查
        for (int i = length - 1; i >= 0; --i)
        {
            //检查是否有低位进位, 计算当前位的值
            int nSum = number[i] - '0' + nTakeOver;
    
            if (i == length - 1) //个位+1
                ++nSum;
    
            if (nSum >= 10) //产生进位
            {
                if (i == 0) //检查是否为首位进位
                    isOverFlow = true; //溢出
                else
                {
                    nSum -= 10; //进位归零
                    nTakeOver = 1; //进位标志置位1
                    number[i] = '0' + nSum; //当前位设置为0
                }
            }
            else
            {
                number[i] = '0' + nSum;
                break; //只有发生进位才从头到尾检查
            }
        }
        return isOverFlow;
    }
    
    // ====================方法二====================
    void Print1ToMaxOfNDigits_2(int n)
    {
        if (n <= 0)
            return;
    
        char* number = new char[n + 1];
        number[n] = '';
    
        for (int i = 0; i < 10; ++i)
        {
            number[0] = i + '0';
            Print1ToMaxOfNDigitsRecursively(number, n, 0); //首位循环
        }
        delete[] number;
    }
    
    void Print1ToMaxOfNDigitsRecursively(char* number, int length, int index)
    {
        if (index == length - 1) //如果是个位
        {
            PrintNumber(number);
            return;
        }
    
        for (int i = 0; i < 10; ++i)
        {
            number[index + 1] = i + '0'; 
            Print1ToMaxOfNDigitsRecursively(number, length, index + 1); //次一位递归
        }
    }
    
    // ====================公共函数====================
    // 字符串number表示一个数字,数字有若干个0开头
    // 打印出这个数字,并忽略开头的0
    void PrintNumber(char* number)
    {
        bool isBeginning0 = true; //首位是否为0
        int length = strlen(number);
    
        for (int i = 0; i < length; ++i)
        {
            //找到非零值后开始打印
            if (number[i] != '0' && isBeginning0)
                isBeginning0 = false;
            
            if (!isBeginning0)
            {
                printf("%c", number[i]);
            }
        }
        printf("	");
    }
    // ====================测试代码====================
    void Test(int n)
    {
        printf("Test for %d begins:
    ", n);
    
        Print1ToMaxOfNDigits_1(n);
        Print1ToMaxOfNDigits_2(n);
    
        printf("
    Test for %d ends.
    ", n);
    }
    
    int main(int argc, char* argv[])
    {
        Test(1);
        Test(2);
        Test(3);
        Test(0);
        Test(-1);
    
        return 0;
    }
    测试代码

    分析:大数用数组或者字符串实现。这个题确实有点绕,看了很久。

     

  • 相关阅读:
    Django框架----路由系统(详细)
    Django框架----路由系统、视图和模板(简单介绍)
    Django框架----模板继承和静态文件配置
    Django框架----模板语法
    毕昇杯之无线通信模块
    新版本ubuntu13.10软件安装
    毕昇杯总结1
    调试程序的方法总结
    新年,新气象
    基于51,人体红外感应和RC522的门禁系统
  • 原文地址:https://www.cnblogs.com/ZSY-blog/p/12562182.html
Copyright © 2011-2022 走看看