零基礎學演算法->階乘
阿新 • • 發佈:2019-03-10
階乘
在數學中,正整數的階乘(英語:factorial)是所有小於及等於該數的正整數的積,計為n!
例如5的階乘為5!,其值=120; 5!=5x4x3x2x1=120
用遞迴計算階乘
一般數字的階乘可以用遞迴的方法進行計算。
以下用遞迴計算1~12階乘值;階乘的值是以指數進行增長。
Sub Factorial_Main() Dim num%, m% Dim FactorNum& With Sheet9 For num = 1 To 12 m = 5 + num 'if num>13 program will overflow FactorNum = Factorial_Recursion(num) .Cells(m, 1) = num .Cells(m, 2) = FactorNum Next num End With Debug.Print Timer End Sub 'Factorial by Recursion Method Function Factorial_Recursion(ByVal n) If n <= 1 Then Factorial_Recursion = 1 Exit Function Else Factorial_Recursion = n * Factorial_Recursion(n - 1) End If End Function
大數階乘
一般階乘的值都比較大,這時遞迴的方法不可行。此時需要用陣列儲存階乘結果來進行計算。
思路:
1. 當前值乘以陣列中的值
2. 將結果儲存到陣列中
3. 判斷每個元素是否需要進位
4. 使用一個數組來儲存階乘每一位結果
以下是1~100的階乘
具體程式碼如下:
'log10:https://baike.baidu.com/item/%E5%AF%B9%E6%95%B0%E5%87%BD%E6%95%B0/6013318?fr=aladdin
'Calculate the Carry
Function Carry_Bit(ByRef Bit, ByVal Pos)
Dim i&
Dim Carry
Carry = 0 'Initial
For i = 1 To Pos 'Check 1~Pos whether need carry bit
Bit(i) = Bit(i) + Carry 'Current value+Carry value
If Bit(i) <= 9 Then '<9 no need carray bit
Carry = 0
ElseIf Bit(i) > 9 And i < Pos Then '>9 but <highest digit
Carry = Int(Bit(i) / 10) 'Save carry
Bit(i) = Bit(i) Mod 10 'one digit
ElseIf Bit(i) > 9 And i >= Pos Then '>9 and highest digit
Do While Bit(i) > 9
Carry = Int(Bit(i) / 10) 'Save carry
Bit(i) = Bit(i) Mod 10 'one digit
i = i + 1
Bit(i) = Carry 'Save the carry
Loop
End If
Next i
Carry_Bit = Bit 'Return the Array
End Function
'Calculate multiple number factor
'Loop m
Sub Factorial_BigNumber_Multiple()
Dim num
Dim Digit, sum
Dim i, j
Dim Fact()
Dim Count, Str$
Dim m, n
With Sheet10
For m = 10 To 43
sum = 0: Digit = 0
num = .Cells(m, 10).Value 'Input Value
For i = 1 To num 'Calculate Result digit
sum = Log10(i) + sum
Next i
Digit = Int(sum) + 1 'Length of Data
ReDim Fact(1 To Digit) 'Allocate Array
For i = 1 To Digit 'Initial Array
Fact(i) = 0
Next i
Fact(1) = 1 'Setup 1st digit
For i = 1 To num 'Loop fact num
Pos = Highest_Digit(Fact, Digit) 'Record highest digit
For j = 1 To Pos
Fact(j) = Fact(j) * i 'fact(n-1)xN
Next j
Fact = Carry_Bit(Fact, Pos) 'process carry bit
Next i
Pos = Highest_Digit(Fact, Digit) 'Record highest digit
' m = 10
n = 12 'Initial
i = Pos
Str = "'"
Count = 0
Do While i <= Pos And i >= 1
Count = Count + 1
Str = Str & Fact(i)
If Count Mod 5 = 0 Then
.Cells(m, n) = Str
Str = "'"
n = n + 1
End If
If i = 1 And Str <> "" Then .Cells(m, n) = Str
i = i - 1
Loop
.Cells(m, 11) = Count
Next m
End With
Debug.Print Timer
End Sub
'Find Hightest digit
Function Highest_Digit(Arr, n)
Dim i
For i = n To 1 Step -1
If Arr(i) <> 0 Then
Highest_Digit = i
Exit Function
End If
Next i
End Function
'Function for Log10
Function Log10(ByVal x) As Double
Dim nLog10
nLog10 = Log(x) / Log(10)
Log10 = nLog10
End Function