|
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件 ★ 免费下载 ★ ★ 使用帮助★
本帖最后由 小麦和小麦 于 2014-2-22 00:04 编辑
Sub bcfhdg(r%, s$, i%, t%) '不重复组合求和的递归过程代码
'参数s是组合结果的文本格式、r是组合结果的和值、i是递归进程位置指针、t是组合抽取个数指针
Dim j%
cnt = cnt + 1 '递归计算次数递增+1
p = Split(s, "+")
For j = 1 To UBound(p)
jg(0, j) = p(j) '当前递归结果分解存入状态栈,以便下一次递归是检查比对
Next
If r >= h1 And r <= h2 Then '如果本次递归组合结果的和值已经在总和目标范围内,则:
If n > m Or t = n Then '如果参数n>m是则结果都要,或者n在1-m之间时必须t=n即抽取个数正好符合条件。
If t > jg(0, 0) Then jg(0, 0) = t
jg(k, -1) = t出现下标越界,如何更改
For j = 1 To UBound(p)
jg(k, j) = p(j) '符合总和条件的本次递归结果写入结果数组。
Next
jg(k, 0) = "=" & Mid(s, 2) '第一列文本格式改写为=计算式,最后输出结果时直接得到计算式结果。
k = k + 1 '结果序号递增+1
End If
'Exit Sub '退出以后的递归进程,加速计算过程。
'注意:如果原始数据数值间隔小、目标和值的范围相对较大时,则这一句要注释掉,否则会漏掉一些正确的答案。
End If
If t = n Then Exit Sub 'n>m → go on 当n参数>m时应该继续,而n在1-m之间时因为t已经满足抽取个数则可退出递归进程。
For j = i + 1 To m '递归遍历检查所有原始元素
If r + sj(j, 1) > h2 Then Exit For '如果本次递归结果的和值已经大于总和目标范围上限,则可退出循环了。
If CStr(sj(j, 1)) <> jg(0, t + 1) Then '检查本次递归进程中最新位置值,和前面上次递归状态栈比对,不重复才可继续
If t < n - 1 Then jg(0, t + 2) = "" '递归最新状态栈位清空,否则会对下一次递归的比对造成错误干扰。
Call bcfhdg(r + sj(j, 1), s & "+" & sj(j, 1), j, t + 1) '满足条件时,继续调用递归进行下一个组合位置的递归计算。
End If
Next j
End Sub
|
|