|
aoe1981 发表于 2014-1-19 23:27
我测试到的一维数组最大上标是9637 0679,运行了24秒,得出素数个数556 4258,稠密度约5.77%。上标为9637 ...
你这个代码算法很明确,就是筛子法。
但是即使在VBA代码中,也还是有改进余地。
我研究了一下,做了test2、test3、test4一共3个阶段的改进,
现在test4可以达到Excel VBA算法的极限了。
我目前测试最大n=25*10^7 也可以计算,而且速度提高不少。
下面代码你去验证一下吧:- Const n As Long = 25 * 10 ^ 7 'k=13,679,317
- Sub SpeedCompare()
- Dim i&, j&, n&, p&
- p = 0
-
- Debug.Print " ": Debug.Print "-Begin-"
- For j = 4 To 4
- tms = Timer
- For i = 1 To 10 ^ p
- Run "Test" & j
- Next
- Debug.Print "Test" & j & ": " & Format(Timer - tms, "0.0000s")
- Next
- Debug.Print "--End--"
- End Sub
- Sub test1()
- Dim i&, j&, k&, flag() As Boolean, arr&(), tms#
- ' tms = Timer
- ReDim flag(n), arr(n)
- For i = 2 To Sqr(n)
- If Not flag(i) Then
- For j = 2 * i To n Step i
- flag(j) = True
- Next
- End If
- Next
-
- For i = 3 To n
- If Not flag(i) Then arr(k) = i: k = k + 1
- Next
- ReDim Preserve arr(k - 1)
- ' MsgBox Format(Timer - tms, "0.000s ") & k
- ' If k < 65536 Then [a:a] = "": [a1].Resize(k) = Application.Transpose(arr)
- End Sub
- Sub test2()
- Dim i&, j&, k&, flag() As Boolean, arr&(), tms#
- ' tms = Timer
-
- ReDim flag(n), arr(n \ 10)
- For i = 2 To n Step 2
- flag(i) = True
- Next
- For i = 3 To Sqr(n) Step 2
- If Not flag(i) Then
- For j = 3 * i To n Step i * 2
- flag(j) = True
- Next
- End If
- Next
-
- For i = 3 To n
- If Not flag(i) Then arr(k) = i: k = k + 1
- Next
- ReDim Preserve arr(k - 1)
- ' MsgBox Format(Timer - tms, "0.000s ") & k
- ' If k < 65536 Then [b:b] = "": [b1].Resize(k) = Application.Transpose(arr)
- End Sub
- Sub test3()
- Dim i&, j&, k&, flag() As Boolean, arr&(), tms#
- ' tms = Timer
-
- ReDim flag(n \ 2), arr(n \ 10)
- For i = 3 To Sqr(n) Step 2
- If Not flag((i + 1) / 2) Then
- For j = 3 * i To n Step i * 2
- flag((j + 1) / 2) = True
- Next
- End If
- Next
-
- For i = 2 To n \ 2
- If Not flag(i) Then arr(k) = i * 2 - 1: k = k + 1
- Next
- ReDim Preserve arr(k - 1)
- ' MsgBox Format(Timer - tms, "0.000s ") & k
- ' If k < 65536 Then [c:c] = "": [c1].Resize(k) = Application.Transpose(arr)
- End Sub
- Sub test4()
- Dim i&, j&, k&, m&, t&, flag() As Boolean, arr&(), tms#
- tms = Timer
- m = n \ 2
- ReDim flag(m)
- ' If n < 10 ^ 6 Then ReDim arr(m) Else ReDim arr(m \ 5)
-
- For i = 2 To Sqr(n) \ 2
- If Not flag(i) Then
- t = i * 2 - 1
- For j = (i * 3 - 1) To m Step t
- ' t2 = j * 2 - 1
- flag(j) = True
- Next
- End If
- Next
-
- For i = 2 To m - 2
- If Not flag(i) Then k = k + 1 'arr(k) = i * 2 - 1: k = k + 1
- Next
- ' ReDim Preserve arr(k - 1)
- MsgBox Format(Timer - tms, "0.000s ") & Format(k, "#,##0")
- ' If k < 65536 Then [d:d] = "": [d1].Resize(k) = Application.Transpose(arr)
- End Sub
复制代码 |
|