劍指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}\t", 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] = '\0';
            
        // 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("\t");
    } 

  這里要注意的是:當數字不夠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();
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM