|
改用递归方法计算,比原来的二进制遍历计算要快很多。- Public sj, jg(), m, n, k, jg2(), h, cnt
- Sub kagawa()
- tms = Timer
- m = [a1].End(4).Row - 1: n = [b5]:: h = [b2]
- sj0 = [a2].Resize(m): [a2].Resize(m).Sort [a2], 1, , , 2
- sj = [a2].Resize(m)
- [a2].Resize(m) = sj0
- If n > m Then AC = 65536 Else AC = WorksheetFunction.Combin(m, n)
- If AC > 65535 Then ReDim jg(65535, n) Else ReDim jg(AC, n)
- k = 1: cnt = 0
- ' ReDim jg2(65536, 0)
-
- Call bcfhdg("", 0, 0, 0)
-
- jg(0, 0) = "Summary": For i = 1 To n: jg(0, i) = "n" & i: Next
- [e1].CurrentRegion = "": If k > 1 Then [e1].Resize(k, n + 1) = jg
- ' If cnt > 1 Then If cnt > 65535 Then [d1].Resize(65536) = jg2 Else [d1].Resize(cnt) = jg2
- [d1] = "<= " & h & " Detail: " & cnt - 1
- [e1].Resize(, n + 2).EntireColumn.AutoFit
- MsgBox "Calc " & cnt - 1 & " ,Get " & k - 1 & " result." & vbCr & Format(Timer - tms, "0.000s")
- End Sub
- Sub bcfhdg(s, r, i, t%)
- ' If cnt < 65536 Then jg2(cnt, 0) = s '"=" & Mid(s, 2)
- cnt = cnt + 1
-
- p = Split(s, "+")
- For j = 1 To UBound(p)
- jg(0, j) = p(j)
- Next
-
- If r = h Then
- If n > m Or t = n Then
- For j = 1 To UBound(p)
- jg(k, j) = p(j)
- Next
- For j = UBound(p) + 1 To n
- jg(k, j) = ""
- Next
- jg(k, 0) = "=" & Mid(s, 2)
- k = k + 1
- End If
- Exit Sub
- End If
- If t = n Then Exit Sub 'n>m → go on
-
- For j = i + 1 To m
- If r + sj(j, 1) > h Then Exit For
- If CStr(sj(j, 1)) <> jg(0, t + 1) Then
- If t < n - 1 Then jg(0, t + 2) = ""
- Call bcfhdg(s & "+" & sj(j, 1), r + sj(j, 1), j, t + 1)
- End If
- Next j
- End Sub
复制代码 |
|