零基础学算法->阶乘

阶乘

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

用递归计算阶乘

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

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

cd529ef68b572769b05aeef2475ffacc729.jpg

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

cefb3de79a9bab435dc29418b0bf66f207a.jpg

3ba69b3e4a45f8252420b3ab9d558ad97e9.jpg

以下是1~100的阶乘

39112ec251f0b8b6132fc251604e1d0add8.jpg

具体代码如下:

'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

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值