|
楼主 |
发表于 2019-6-13 21:45
|
显示全部楼层
我不是习惯“递归”的方法实现排列,以下“递归排列”修改自香川女侠的“递归组合”算法:
- Option Explicit
- Dim sj$(), jg$(), m&, n&, cnt&, k&, ljf$, c%()
- Sub 递归排列() 'aoe1981
- Dim sj0(), tms!, i&
- tms = Timer
- With Sht1
- m = .Range("b2").Value '元素总个数
- n = .Range("b4").Value '选取元素个数
- sj0 = .Range("a2").Resize(m).Value '元素
- ljf = .Range("b6").Value '连接符
- cnt = Application.Permut(m, n) '排列总数
-
- ReDim sj$(1 To m), c%(1 To m)
- For i = 1 To m '二维转一维
- sj(i) = sj0(i, 1)
- Next i
-
- ReDim jg$(1 To cnt, 1 To 1)
- k = 0
- Call dgPL("", 1)
-
- .Range("d2").Resize(Rows.Count - 1, 1).Value = ""
- .Range("d2").Resize(cnt, 1).Value = jg
- End With
- MsgBox "用时:" & Timer - tms & "秒,共产生:" & cnt & "个排列。"
- End Sub
- Sub dgPL(s$, t&)
- Dim j&
- For j = 1 To m
- If c(j) = 0 Then
- c(j) = 1
- If t = n Then
- k = k + 1
- jg(k, 1) = Mid(s & ljf & sj(j), 2)
- c(j) = 0
- Else
- Call dgPL(s & ljf & sj(j), t + 1)
- c(j) = 0
- End If
- End If
- Next j
- End Sub
复制代码
香川女侠的“递归组合”算法如下:
- Option Explicit
- Dim sj$(), jg$(), m&, n&, cnt&, k&, ljf$
- Sub 递归组合() 'kagawa
- Dim sj0(), tms!, i&
- tms = Timer
- With Sht
- m = .Range("b2").Value '元素总个数
- n = .Range("b4").Value '选取元素个数
- sj0 = .Range("a2").Resize(m).Value '元素
- ljf = .Range("b6").Value '连接符
- cnt = Application.Combin(m, n) '组合总数
-
- ReDim sj$(1 To m)
- For i = 1 To m '二维转一维
- sj(i) = sj0(i, 1)
- Next i
-
- ReDim jg$(1 To cnt, 1 To 1)
- k = 0
- Call dgZH("", 0, 1)
-
- .Range("d2").Resize(Rows.Count - 1, 1).Value = ""
- .Range("d2").Resize(cnt, 1).Value = jg
- End With
- MsgBox "用时:" & Timer - tms & "秒,共产生:" & cnt & "个组合。"
- End Sub
- Sub dgZH(s$, i&, t&)
- Dim j&
- For j = i + 1 To m
- If t = n Then
- k = k + 1
- jg(k, 1) = Mid(s & ljf & sj(j), 2)
- Else
- Call dgZH(s & ljf & sj(j), j, t + 1)
- End If
- Next j
- End Sub
复制代码
附件如下:
我的排列算法_aoe1981.zip
(29.11 KB, 下载次数: 14)
或许您的代码更高效,我的侧重点在于“实现”,其实也并无什么“庞大”的应用需求。标记变量c(i)算是粗糙地受了您的影响。
当然,这也是直接生成所有排列,再去重的思路。去重部分我没做,数据透视表等也可以轻易实现。
看来,“有相同元素的排列”直接生成的算法是困难的。也有可能是我在一楼的计算思路本身就是繁琐的。解决非常问题,或许必是要有“非常的思路”,我便只作胡想罢了。
|
|