第1个回答 2009-07-24
我这个算法是按数组的下标来排列,这样可以适用多种数据类型和数值。主要就是进位函数,构想很简单,比如5个数排列,就好象从12345 to 54321的循环,进位函数就是对已经排列过的数组下标进行累加,实现逢5进1,同时过滤掉重复数字...
Option Explicit
'全排列个数
Function GetPermNum(ByVal M As Long) As Long
Dim i As Long
For i = M - 1 To 1 Step -1
M = M * i
Next
GetPermNum = M
End Function
'进位
Sub PermCarry(Index() As Long, Length As Long, bolExist() As Boolean)
'Index:要排列的数组的下标,Length数组最大下标,bolExist标志当前使用的下标
Dim Idx As Long
Idx = Length
bolExist(Index(Idx)) = False
Do
Index(Idx) = Index(Idx) + 1
If Index(Idx) > Length Then
Idx = Idx - 1
bolExist(Index(Idx)) = False
Else
If Not bolExist(Index(Idx)) Then
bolExist(Index(Idx)) = True
Exit Do
End If
End If
Loop
Do While Idx < Length
Idx = Idx + 1
Index(Idx) = 0
Do While bolExist(Index(Idx))
Index(Idx) = Index(Idx) + 1
Loop
bolExist(Index(Idx)) = True
Loop
End Sub
'输出单个排列的结果
Function GetResultItem(arr As Variant, Index() As Long) As String
Dim i As Long
ReDim tmp(UBound(Index))
For i = 0 To UBound(tmp)
tmp(i) = arr(Index(i))
Next
GetResultItem = Join(tmp)
End Function
Sub GetResult(arr As Variant, Result As Variant)
Dim i As Long
Dim n As Long, Length As Long
Dim Index() As Long
Dim bolExist() As Boolean
Length = UBound(arr)
ReDim Index(Length)
ReDim bolExist(Length)
For i = 0 To Length
Index(i) = i
bolExist(i) = True
Next
n = GetPermNum(Length + 1)
ReDim Result(n - 1)
Result(0) = GetResultItem(arr, Index)
For i = 1 To n - 1
PermCarry Index, Length, bolExist
Result(i) = GetResultItem(arr, Index)
'DoEvents
Next
End Sub
Private Sub Command1_Click()
Dim arr, Result
arr = Array("A", "B", "C")
GetResult arr, Result
Debug.Print Join(Result, vbCrLf)
End Sub
第2个回答 2009-07-23
Private Sub Form_Click()
arr = GetPArr(4)
For i = 0 To UBound(arr, 2)
For j = 0 To UBound(arr, 1)
Print arr(j, i);
Next j
Print
Next i
End Sub
Public Function GetPArr(ByVal m As Integer)
Dim arr() As Byte
Dim a As Long
Dim i, j, k, n
ReDim arr(m - 1, 0)
For i = 0 To m - 1
arr(i, 0) = i + 1
Next i
For n = 2 To m
ReDim Preserve arr(m - 1, n * (a + 1) - 1)
For i = 0 To a
For k = 1 To n - 1
a = a + 1
For j = 0 To n - k - 2
arr(j, a) = arr(j, i)
Next j
arr(n - k - 1, a) = arr(n - 1, i)
For j = n - k To n - 1
arr(j, a) = arr(j - 1, i)
Next j
For j = n To m - 1
arr(j, a) = arr(j, i)
Next j
Next k
Next i
Next n
GetPArr = arr
End Function