零基础学算法->阶乘

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

阶乘

在数学中,正整数的阶乘(英语:factorial)是所有小于及等于该数的正整数的积,计为n!
例如5的阶乘为5!,其值=120; 5!=5x4x3x2x1=120

用递归计算阶乘

一般数字的阶乘可以用递归的方法进行计算。

以下用递归计算1~12阶乘值;阶乘的值是以指数进行增长。

零基础学算法->阶乘_第1张图片

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. 使用一个数组来保存阶乘每一位结果

零基础学算法->阶乘_第2张图片

零基础学算法->阶乘_第3张图片

以下是1~100的阶乘

零基础学算法->阶乘_第4张图片

具体代码如下:

'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  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

 

转载于:https://my.oschina.net/tedzheng/blog/3019815

你可能感兴趣的:(零基础学算法->阶乘)