演算法實現求n的階乘(防止溢位)
阿新 • • 發佈:2019-02-16
求大整數n階乘,在找工作筆試和麵試的過程中,不止一次遇到這個問題,用一個for迴圈迭代出的結果肯定是不行的,即直接用int,預設是32位,它能表示的最大值為2,147,483,647,但是12的階乘為479,001,600,13的階乘為6,227,020,800,所以當n為13的時候已經溢位了。所以當n為更大的值時,需要採用巧妙的方法來防止溢位。
我們可以用陣列的方式來儲存每一位資料。
具體程式碼如下:
直接看程式碼比較難理解,可以舉個例子,比如說我們現在得到了4!= 24,在陣列中是以倒序的方式儲存,即42,a[1] = 4,a[2] = 2(陣列下標從1開始),現在要計算5!,內層for迴圈對目前的兩位4和2進行處理,即每一位都乘以5,首先a[1] = a[1]*5 + 0(h)= 20,h從0變為2,a[1] = 0;然後a[2] = a[2] * 5 + 2 = 12,h從2變為1,a[2] = 2;這時內層for迴圈執行結束。#include <iostream> #include <cstdio> #define MAX 40000 using namespace std; int main(void) { int n; while(scanf("%d",&n)!=EOF&&n>=0) { int i,j; int a[MAX]; //存數運算結果 int p,h; //p儲存當前結果的位數,h為進位 a[1]=1; p=1; for(i=2;i<=n;i++) //迴圈與2,3,4.....n相乘 { for(j=1,h=0;j<=p;j++) //讓a[]的每位與i相乘 { a[j] = a[j] * i + h ; h = a[j] / 10 ; a[j] = a[j] % 10 ; } while(h>0) //如果h不為0 { a[j] = h % 10 ; h = h / 10 ; j++; } p = j - 1 ; //將當前的位數賦給p } for(i=p;i>=2;i--) { printf("%d",a[i]); } printf("%d\n",a[i]); } return 0; }
總結1:內層for迴圈的作用是更新已經存在的位數中的每一位與i的乘積的結果.
接著執行while迴圈,目前h = 1,a[3] = 1,h 從1變為0,然後退出while迴圈。處理結束就得到了5! = 120.p的位數增加到3.
總結2:while迴圈的作用是計算p更新之前的位數之後的進位,比如說p = 2的時候,陣列中為42,然後內層for迴圈把42更新為02,while迴圈增加進位1,整個陣列變為021.
這樣就可以計算任意數的階乘,而不用擔心溢位,自己的一點總結,積累知識,溫故而知新,為自己加油!