看了northwolves 的文章大数阶乘的计算(三) http://dev.csdn.net/article/28/28432.shtm 很有启发,联想起以前自己编写过一个类似的函数,方法与其差不多,都是动态数组的增位保存方式。效率上比northwolves兄要差一些,大约相差50%;当时以为是最快的阶乘算法了,所以看到这篇文章很是钦佩!
不过,我总觉得,这个算法还有可优化的余地,于是,又重新做了点新尝试,不想大获成功,效率比大数阶乘的计算(三)一下子又提高了5倍多,而且算法简单得惊人,故不敢独吞,赶紧贴出与大家共享。
Option Explicit Private Function cacl(num As Long) As String Dim numlen As Long, last As Long, x As Long Dim i As Long, m As Long, n As Long Dim result() As Long, starttime As Single numlen = 1 starttime = Timer ReDim result(1 To numlen) result(1) = 1 x = 1 Do While x <= num last = 0 For i = 1 To numlen m = result(i) * x + last result(i) = m Mod 10 last = m \ 10 Next If last > 0 Then n = Len(CStr(last)) ReDim Preserve result(1 To numlen + n) For i = 1 To n result(numlen + i) = last Mod 10 last = last \ 10 Next numlen = UBound(result) End If x = x + 1 Loop ReDim s(1 To numlen) For i = 1 To numlen s(i) = result(numlen + 1 - i) Next cacl = Join(s, "") Debug.Print num & "! : 用时 "; Timer - starttime & " 秒, 结果 " & numlen & " 位" End Function
Private Sub Command1_Click() Dim i As Long For i = 1 To 10 cacl i * 100 Next 'For i = 1 To 10 'cacl i * 1000 'Next End Sub
输出结果:(我的机器在运行“计算(三)”时,与其结果相当,所以应是与northwolves兄,同档次的机器)
100! : 用时 0 秒, 结果 158 位 200! : 用时 1.171875E-02 秒, 结果 375 位 300! : 用时 3.515625E-02 秒, 结果 615 位 400! : 用时 4.296875E-02 秒, 结果 869 位 500! : 用时 8.203125E-02 秒, 结果 1135 位 600! : 用时 .1054688 秒, 结果 1409 位 700! : 用时 .15625 秒, 结果 1690 位 800! : 用时 .1992188 秒, 结果 1977 位 900! : 用时 .2617188 秒, 结果 2270 位 1000! : 用时 .3632813 秒, 结果 2568 位 2000! : 用时 1.53125 秒, 结果 5736 位 3000! : 用时 3.75 秒, 结果 9131 位 4000! : 用时 7.171875 秒, 结果 12674 位 5000! : 用时 11.45313 秒, 结果 16326 位 6000! : 用时 16.41016 秒, 结果 20066 位 7000! : 用时 22.83984 秒, 结果 23878 位 8000! : 用时 30.375 秒, 结果 27753 位 9000! : 用时 41.75 秒, 结果 31682 位 10000! : 用时 54.57813 秒, 结果 35660 位
这次输出慢了些,因为我在第一次测试10000!时,只用了47秒。不知会不会还有更快的算法。 
|