|
从m个元素中取n个,产生各种不同的排列……
现在想知道所有排列结果中,第n个位置的具体排列结果,
而不需要事先排出所有结果,则可以使用下述自定义函数。- Function PN(Rng As Range, n, k, Optional InsertWd = "") '给出第k个位置的排列结果
- m = Rng.Count '元素数
- PAM = Application.WorksheetFunction.Permut(m, n)
- If k > PAM Then PN = "> " & PAM: Exit Function '检查k值如果大于可能排列结果,则终止并提示。
-
- Dim s As New Collection '把所有元素加入集合s中待用。
- For i = 1 To m
- s.Add Rng.Cells(i)
- Next
-
- For i = 1 To n - 1 ’按顺序取n-1个值
- j = Int((k - 1) / Application.WorksheetFunction.Permut(m - i, n - i)) Mod (m - i + 1) + 1
- '求k位置序号,按排列值分割以后,再按待排列数,求余转换为序数值,即可从s集合中得到该元素
- '例如:8取4时共1680个排列组合,
- '首先,第1位的排列数应该是按照P(7,3)=210,即8个元素每一个有210种。210 x 8 =1680
- '接下来,第2位的排列数应该是按照P(6,2)=30,即7个元素每一个有30种。30 x 7 =210
- '接下来,第3位的排列数应该是按照P(5,1)=5,即6个元素每一个有5种。5 x 6 =30
- '以此类推,直至倒数第2位结束,因为最后一位的算法不一样的。
-
- PN = PN & s(j) & InsertWd '逐个加入选定元素,并插入分割符号。(默认为空格)
- s.Remove j '从集合s中去掉已经使用过的元素
- Next
- '最后一位,是k位置序号对于剩余数的余数,例如,8取4时取好3个剩最后一位时,还剩5个元素可选
- PN = PN & s((k - 1) Mod (m - n + 1) + 1)
-
- End Function
复制代码 请看附件。 |
|