大数阶乘的计算(五)[1]

[入库:2005年8月18日] [更新:2007年3月25日]

本文简介:选择自 northwolves 的 blog

很难想象只要改动几句代码就可以大幅提高执行的效率,在前几篇文章中我写了几种大数阶乘的算法(http://www.csdn.net/develop/read_article.asp?id=28306http://www.csdn.net/develop/read_article.asp?id=28308http://www.csdn.net/develop/read_article.asp?id=28432),效率都比较低。今日看了homezj(http://www.csdn.net/develop/article/28/28584.shtm )的代码,很受启发,优化如下:

 

<一>按每四位进行一次计算:

sub calcfactorial(byval num as long, optional byref factorial as string)

dim numlen as long, last as long, i as long, j as long, temp as long

dim result() as long, s() as string, stime as double
numlen = 1
stime = timer
redim result(1 to numlen)
result(1) = 1
i = 0
do while i < num
i = i + 1
   last = 0
   for j = 1 to numlen
        temp = result(j) * i + last
        result(j) = temp mod 10000
        last = temp \ 10000
   next
   do while not last = 0
           redim preserve result(1 to numlen + 1)
            result(numlen + 1) = last mod 10000
            last = last \ 10000
           numlen = ubound(result)
  loop
loop
redim s(1 to numlen)
for i = 2 to numlen
s(i) = format(result(numlen + 1 - i), "0000")
next
s(1) = result(numlen)

factorial = join(s, "")
debug.print num & "! : 用时 "; timer - stime & " 秒, 结果 " & len(factorial) & " 位,前5位为 " & left(factorial, 5)
'debug.print factorial
erase s
erase result
end sub

private sub command1_click()
for i = 1 to 20
calcfactorial i * 1000
next
end sub

输出结果:
'1000! : 用时 7.82500000059372e-02 秒, 结果 2568 位,前5位为 40238
'2000! : 用时 .391499999997905 秒, 结果 5736 位,前5位为 33162
'3000! : 用时 .968875000005937 秒, 结果 9131 位,前5位为 41493
'4000! : 用时 1.78174999999464 秒, 结果 12674 位,前5位为 18288
'5000! : 用时 2.84412500000326 秒, 结果 16326 位,前5位为 42285
'6000! : 用时 4.20387500000652 秒, 结果 20066 位,前5位为 26839
'7000! : 用时 5.84387500000594 秒, 结果 23878 位,前5位为 88420
'8000! : 用时 7.75012500000594 秒, 结果 27753 位,前5位为 51841
'9000! : 用时 9.98512500000652 秒, 结果 31682 位,前5位为 80995
'10000! : 用时 12.5160000000033 秒, 结果 35660 位,前5位为 28462
'11000! : 用时 15.2818750000006 秒, 结果 39681 位,前5位为 31624
'12000! : 用时 18.4063750000059 秒, 结果 43742 位,前5位为 12018
'13000! : 用时 21.7975000000006 秒, 结果 47838 位,前5位为 77871
'14000! : 用时 25.5320000000065 秒, 结果 51969 位,前5位为 13864
'15000! : 用时 29.5627499999973 秒, 结果 56130 位,前5位为 27465
'16000! : 用时 33.90625 秒, 结果 60320 位,前5位为 51187
'17000! : 用时 38.5786249999946 秒, 结果 64538 位,前5位为 13797
'18000! : 用时 43.5477499999979 秒, 结果 68781 位,前5位为 13525
'19000! : 用时 48.84375 秒, 结果 73048 位,前5位为 18269
'20000! : 用时 54.4375 秒, 结果 77338 位,前5位为 18192

 

<二>按每五位进行一次计算:

sub calcfactorial(byval num as long, optional byref factorial as string)

dim numlen as long, last as long, i as long, j as long, temp as long

dim result() as long, s() as string, stime as double

numlen = 1
stime = timer
redim result(1 to numlen)
result(1) = 1
i = 0
do while i < num
i = i + 1
   last = 0
   for j = 1 to numlen
        temp = result(j) * i + last
        result(j) = temp mod 100000
        last = temp \ 100000
   next
   do while not last = 0
           redim preserve result(1 to numlen + 1)
            result(numlen + 1) = last mod 100000
            last = last \ 100000
           numlen = ubound(result)
  loop
loop
redim s(1 to numlen)
for i = 2 to numlen
s(i) = format(result(numlen + 1 - i), "00000")
next
s(1) = result(numlen)

factorial = join(s, "")
debug.print num & "! : 用时 "; timer - stime & " 秒, 结果 " & len(factorial) & " 位,前5位为 " & left(factorial, 5)
'debug.print factorial
erase s
erase result
end sub

private sub command1_click()
for i = 1 to 20
calcfactorial i * 1000
next
end sub

输出结果:

1000! : 用时 6.26250000059372e-02 秒, 结果 2568 位,前5位为 40238

本文关键:数组 阶乘
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top