|
Function Arr_SerialCombinPermut(m&, n&, Optional z& = 0, Optional l& = 0)
Dim i&, j&, k&, t&
If z = 0 Then k = (m - l + 1) ^ n
If z = 1 Then k = WorksheetFunction.Combin(m, n): l = 1
If z = 2 Then k = WorksheetFunction.Permut(m, n): ReDim c&(1 To m)
ReDim a&(1 To n), b&(k - 1, 1 To n) '创建两个数组,分别用于存放3个“数种”各数位的数码和3个“数种”的序列。
For j = 1 To n '给序列第一个位置赋值
If z = 0 Then a(j) = l '自然数序列第一个,3位分别为0 0 0
If z = 1 Then a(j) = j '组合数序列第一个,3位分别为1 2 3,
If z = 2 Then a(j) = j: c(j) = 1 '排列数序列第一个,3为分别为1 2 3,同时创建状态监测数组,用于监视数码是否被使用,如已使用则状态为1,否则为0。
b(0, j) = a(j) 'ar(a(j))
Next
For i = 1 To k - 1 ' 序列循环头
For j = n To 1 Step -1 '从低位到高位遍历每一个数的数位。
If z = 0 Then
If a(j) < m Then a(j) = a(j) + 1: Exit For '对自然数序列,该数位中要装填的数码是前一个自然数的对应数位中的数码+1。否则将“进位”到高一位,并对高一位进行相似的处理。
ElseIf z = 1 Then
If a(j) < m - n + j Then a(j) = a(j) + 1: Exit For '对组合数序列,该数位的数码也+1,但最大不得超过该数位(该次选择)能选取的最大数码(最多种数)。否则将“进位”到高一位
Else 'If z = 2 Then
c(a(j)) = 0 '对排列数序列,将每一位使用的数码恢复为未使用。
For t = a(j) + 1 To m '搜寻尚未使用的数码,
If c(t) = 0 Then Exit For
Next
If t <= m Then c(t) = 1: a(j) = t: Exit For '然后装填在该数位,并标记该数码已使用。
End If
Next
For j = j + 1 To n
If z = 0 Then '对自然数序列,因为产生了“进位”,需要将低一位的数位中装填数码恢复为“l”(数码列表中的最小的那个)。
a(j) = l
ElseIf z = 1 Then '对组合数序列,因为也产生了“进位”,低一位的要装填的数码个数要多一个。
a(j) = a(j - 1) + 1
Else 'If z = 2 Then '对排列数序列,
For t = 1 To m '低一位的要装填的应该是尚未使用的数码中的第一个。
If c(t) = 0 Then Exit For
Next
c(t) = 1: a(j) = t '通过紧前循环步骤,找出了尚未使用的数码中的第一个,并将其装填在该数位。
End If
Next
For j = 1 To n
b(i, j) = a(j) 'ar(a(j))
Next
Next
Arr_SerialCombinPermut = b
End Function |
评分
-
2
查看全部评分
-
|