|
楼主 |
发表于 2015-1-29 16:56
|
显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
算法 真正的突破:
这个比test2速度又快了4-5倍……比test1已经快了50-60倍了。- Sub test5()
- Dim i&, j&, k&, n&, s&
- n = [a1]
- ReDim a(1 To n) As Boolean
-
- For i = 2 To Sqr(n)
- If Not a(i) Then
- For j = i + i To n Step i '这里是改进关键,注意循环步长 i 是变化的。
- a(j) = True
- Next
- End If
- Next
-
- ReDim b&(1 To n)
- For i = 1 To n
- If a(i) = False Then k = k + 1: b(k) = i
- Next
- ReDim Preserve b&(1 To k)
- ' [a2] = k: If k < 65536 Then [b:b] = "": [b1].Resize(k) = Application.Transpose(b)
- End Sub
复制代码 本次算法的重大改进,在于彻底废除了Mod算法,而改为数组定位后直接标记的做法。
原理在于,数组 a(1 To n) 是完全按顺序排列的,
因此,如果其中某些元素的位置正好能被整数 i 整除,
那么它们一定是 i、i+i、i+i+i、i+i+i+i、i+i+i+i+i…… 即 i 的整数倍实际上就是以 i 开始、步长= i 的等差数列。
或者直接简化为 i、i*2、i*3、i*4、i*5、
因此,无需进行Mod计算,即可按照顺序,用For循环来直接标记所有 i 的整数倍的合数所在位置了。
仅需理解这一句的代码:
For j = i + i To n Step i
i + i 即 i*2 含义是: 该素数 i 的本位无需排除,之后的 i+i、 或 i*2 位置开始直到终点n,以步长 i 循环即可。
呵呵。
由于省去了大量的Mod计算的时间,所以代码速度大为提高。
|
评分
-
3
查看全部评分
-
|