算法題007 計算n的階乘


階乘的計算

階乘的定義

  n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1

 

 

簡單的程序代碼(可以算較小的階乘)

  沒有考慮變量表達范圍,假設所得結果用long型表示。

  這里需要注意的是0的階乘應該是1.

n較小的階乘算法
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
    int n = 0;
    long result = 0;

    while( cin >> n)
    {
        if(n > 0)
        {
            result = n;
            while(n > 1)
            {
                result *= (n-1);
                --n;
            }
        }
        else if (n == 0)
        {
            result = 1;
        }

        cout << result << endl;
    }

    return 0;
}

 

  這個程序的主要問題就是long的選取,long型是4個字節,32位,因為是帶符號的,能表示的范圍最大不超過2的31次方,即不超過10的10次方。

  即long型可以表示的數肯定是十進制下的10位數之內的。

  而14的階乘就已經是一個11位數了。

  (事實上13的階乘就已經超過了long的表示范圍,因為13的階乘的最高位是6,而2的31次方最高位是2。)

  所以這個程序只能計算12以下的數的階乘。

  考慮過將數據類型進一步改為long double,得到的結果是科學計數法顯示的,只有有限的有效數字,精度不高,並且當n進一步增大再次超過表示范圍的時候呢?所以還是需要另外的處理辦法。

 

 

大數階乘運算  

  當n大於等於20時,因為運算結果超出了long型的表示范圍,所以必須采取大數字的一般處理方法:用數組表示。

  程序如下,自己寫的,沒有仔細研究文后的參考資料。 

大數階乘運算
#include <iostream>
using namespace std;



int main(int argc, char* argv[])
{
    int n = 0;
    int number[21] = {0};
    int bitCount = 0;//記錄所用到的位數下標

    while( cin >> n)
    {
        bitCount = 0;
        if(n > 0)
        {
            //先把n用數組表示,0號元素為個位
            int copyOfN = n;

            for(int i = 0; copyOfN > 0; copyOfN/=10, ++i)
            {
                number[i] = copyOfN % 10;
                bitCount = i;

                //cout << "number: " << number[i] << endl;
                //cout << "bitCount: "<<bitCount <<endl;
            }

            //然后進行階乘運算

            while( --n > 0)
            {
                int carry = 0;
                for(int i = 0; i<= bitCount; ++i)
                {
                    int temp = number[i] * n + carry;

                    number[i] = temp % 10;
                    carry = temp / 10;

                }
                while(carry > 0)
                {
                    //如果有多余的進位,則說明數組需要添加位數
                    //注意,這里由於把第二個乘數當做整體處理,而不是一位一位處理,所以進位可能也不只是一位
                    number[++ bitCount] = carry % 10;
                    carry /= 10;
                }
                
            }


            //最后輸出運算結果
            for(int i = bitCount; i >= 0; --i)
            {
                cout << number[i];
            }
            cout << endl;
        }
        else if (n == 0)
        {
            cout << 1 << endl;
        }
        else
        {
            cout << "負數沒有階乘!" << endl;
        }



    }


    return 0;
}

 

  還是需要細心一些的。

  主要檢查循環變量是否更新,對於進位的理解是否正確等。

  結果用計算器驗證過,並且在九度上提交通過:http://ac.jobdu.com/problem.php?pid=1067

 

 

其他參考資料

  大數運算(采用數組模擬):

http://www.cnblogs.com/dolphin0520/archive/2011/07/16/2108006.html

http://www.cnblogs.com/yuzhaoxin/archive/2011/11/19/2205221.html

http://confach.cnblogs.com/archive/2005/07/14/192703.html

http://www.cnblogs.com/lsx54321/archive/2012/07/20/2601618.html

http://www.cnblogs.com/phinecos/archive/2009/10/06/1578411.html

 


免責聲明!

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



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