• 剑指Offer面试题:11.打印1到最大的n位数


    一、题目:打印1到最大的n位数

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

    二、不同的解法

    2.1 不假思索的解法

      最容易想到的办法是先求出最大的n位数,然后用一个循环从1开始逐个打印:

        static void Print1ToMaxOfNDigitsSimple(int n)
        {
            int number = 1;
            int i = 0;
    
            while (i < n)
            {
                number = number * 10;
                i++;
            }
    
            for (i = 1; i < number; i++)
            {
                Console.Write("{0}	", i);
            }
        }

      初看之下好像没有问题,但是其并没有考虑大数问题,有可能即使用整型(int)或长整型(long)都会溢出。

    2.2 字符串模拟运算的解法

      解决这个问题需要表达一个大数。最常用也是最容易的方法是用字符串或者数组表达大数。该算法的步骤如下:

      Step1.把字符串中的每一个数字都初始化为'0';

      Step2.每一次为字符串表示的数字加1,再打印出来;

        static void Print1ToMaxOfNDigits(int n)
        {
            if (n <= 0)
            {
                return;
            }
            // memset(number,'0',n);
            char[] number = new char[n + 1];
            for (int i = 0; i < n; i++)
            {
                number[i] = '0';
            }
            number[n] = '';
                
            // Increment实现在表示数字的字符串number上增加1
            while (!Increment(number))
            {
                // PrintNumber负责打印出number
                PrintNumber(number);
            }
    
            number = null;
        }
    
        static bool Increment(char[] number)
        {
            bool isOverflow = false;
            int takeOver = 0;
            int length = number.Length - 1;
    
            for (int i = length - 1; i >= 0; i--)
            {
                int sum = number[i] - '0' + takeOver;
                if (i == length - 1)
                {
                    sum++;
                }
    
                if (sum >= 10)
                {
                    if (i == 0)
                    {
                        // 标识已经溢出了
                        isOverflow = true;
                    }
                    else
                    {
                        sum -= 10;
                        takeOver = 1;
                        number[i] = (char)('0' + sum);
                    }
                }
                else
                {
                    number[i] = (char)('0' + sum);
                    break;
                }
            }
    
            return isOverflow;
        }
    
        static void PrintNumber(char[] number)
        {
            bool isBeginning0 = true;
    
            for (int i = 0; i < number.Length; i++)
            {
                if (isBeginning0 && number[i] != '0')
                {
                    isBeginning0 = false;
                }
    
                if (!isBeginning0)
                {
                    Console.Write("{0}", number[i]);
                }
            }
    
            Console.Write("	");
        } 

      这里要注意的是:当数字不够n位的时候,我们在数字的前面补0,打印的时候这些补位的0不应该打印出来。

    三、单元测试

    3.1 封装测试入口

        static void PrintTest(int n)
        {
            Console.WriteLine("Test for {0} begins:", n);
            Print1ToMaxOfNDigits(n);
            Console.WriteLine("Test for {0} ends.", n);
        }

    3.2 测试用例

        static void Main(string[] args)
        {
            PrintTest(1);
            PrintTest(2);
            PrintTest(3);
            PrintTest(0);
            PrintTest(-1);
    
            Console.ReadKey();
        }

  • 相关阅读:
    composer安装Workerman报错:Installation failed, reverting ./composer.json to its original content.
    从零开始搭建linux下laravel 5.5所需环境(三)
    ASPNET Razor 使用 @Ajax.BeginForm 需要注意到的细节
    .NET跨平台
    1172金币
    1044电子表
    1358统计号码牌
    1355疫情防控 数据调查
    1056反向输出一个三位数2
    1071行李托运
  • 原文地址:https://www.cnblogs.com/edisonchou/p/4762114.html
Copyright © 2020-2023  润新知