|
本帖最后由 香川群子 于 2012-10-14 19:50 编辑
具有通用性的代码也调试成功了。
不过,很显然,本代码算法只是特别适合于1-m的连续自然数计算。(因为每一个中间值都是连续存在的)
而对于其它间隔>1或任意随机间隔的序列求和来说,则无法体现速度优势,甚至于变慢了……。
因此,最后的结论是:
如果仅仅用来计算1-m的连续自然数求和,那么【数组预置结果算法】速度是最酷的,目前没有更快的算法。
而如果真正用来求各种任意序列数的定值和,则【倒序差额+末位搜寻+累计和剪枝的算法】是目前最快的、适用性最强的算法代码。- Dim sj, jg(), m%, k, h%
- Sub kagawa_5() '递归组合求和-5 【最优算法最终版】
- '【倒序差额+末位搜寻+次位超r剪枝+不足累计和剪枝 的算法】
- tms = Timer
- h = [b1]
- m = [a1].End(4).Row: ' sj0 = [a1].Resize(m)
- [a1].Resize(m).Sort [a1], 1, , , 2 '如果原始数据乱序则先升序排序
- sj = [a1].Resize(m, 2): ' [a1].Resize(m) = sj0 '排序处理后原始数据恢复原状
-
- sj(1, 2) = sj(1, 1)
- For i = 2 To m
- sj(i, 2) = sj(i - 1, 2) + sj(i, 1)
- Next
-
- ReDim jg(65536, 0)
- Open "D:\Backup\我的文档\kagawa-5.txt" For Output As #1
- k = 0 'tms = Timer
-
- Call dgH5(h, "", m + 1)
-
- Close #1
- MsgBox "Result: " & k & "/ Time: " & Format(Timer - tms, "0.000s")
- If k > 0 And k < 65536 Then [h:h] = "": [h1].Resize(k) = jg
- End Sub
- Sub dgH5(r%, s$, i%)
- Dim j%
-
- For j = 1 To i - 1 '【末位搜寻】
- If r = sj(j, 1) Then
- If k < 65536 Then jg(k, 0) = s & "+" & r
- Print #1, s & "+" & r
- k = k + 1
- Exit For
- ElseIf r < sj(j, 1) Then
- j = j + 1 '【次位超r剪枝】
- Exit For
- End If
- Next
-
- For j = j - 1 To 2 Step -1
- If r > sj(j, 2) Then
- Exit For '【不足累计和剪枝】
- Else
- Call dgH5(r - sj(j, 1), s & "+" & sj(j, 1), j) '【倒序差额递归计算】
- End If
- Next
- End Sub
复制代码 |
|