|
楼主 |
发表于 2014-5-22 21:59
|
显示全部楼层
按照从小到大,排除不重复组合时的代码及附件:- Dim sj&(), jg&(), m&, n&, k&, t&, cnt&, cnt2&
- Sub MultiColumnCombin() 'by kagawa
- tms = Timer
- [ai1].CurrentRegion = ""
- sj0 = [aa1].CurrentRegion.Offset(1, 1)
- '以AA1列中序号的行数决定原始数据区域大小。所以序号不能错!
-
- m = UBound(sj0) - 1: n = UBound(sj0, 2) - 1
- ReDim sj&(1 To m, 1 To n)
- For j = 1 To n
- k = 0
- For i = 1 To m
- If sj0(i, j) Then k = k + 1: sj(k, j) = sj0(i, j)
- Next
- If k > l Then l = k
- Next
- '以上把数据转为Long型数值 可以提高计算速度。
- m = l 'm更新为有效最大行数l 减少无效循环次数。
-
- cnt = InputBox("指定输出行数 cnt=", "", WorksheetFunction.Round(Cells.Rows.Count, -4))
- ReDim jg&(cnt, 1 To n)
- '指定输出行数 如2003 5万行 或2007时 100万行。
-
- k = 0: t = 0: cnt2 = 0: Call dgMN(1) '递归计算 并输出整数行的结果
- If k Then [aj1].Offset(1, (n + 1) * cnt2).Resize(k, n) = jg: [ai1].Offset(, (n + 1) * cnt2) = cnt2 + 1 '输出最后零数行的结果
- MsgBox Format(Timer - tms, "0.00s ") & Format(cnt * cnt2 + k, "#,##0")
- End Sub
- Sub dgMN(j&) '递归过程代码
- Dim l&
- For i = 1 To m '循环本列
- If sj(i, j) = 0 Then Exit For '本列为空时退出
- If sj(i, j) > t Then '确保大于上一列的值t 即可排除重复组合
- jg(k, j) = sj(i, j) '填入组合数据
- If j = n Then '已经到最后一列(=n)时
- k = k + 1
- For l = 1 To n - 1
- jg(k, l) = jg(k - 1, l) '循环复制上一列数据
- Next
-
- If k = cnt Then '如果满足整数行则输出结果
- [aj1].Offset(1, (n + 1) * cnt2).Resize(cnt, n) = jg
- [ai1].Offset(, (n + 1) * cnt2) = cnt2 + 1: cnt2 = cnt2 + 1
- For l = 1 To n - 1
- jg(0, l) = jg(k, l) '循环复制上一列数据
- Next
- k = 0
- End If
- Else
- t = sj(i, j)
- Call dgMN(j + 1) '递归到下一列
- t = sj(i, j)
- End If
- End If
- Next
- End Sub
复制代码 |
评分
-
1
查看全部评分
-
|