Generate list of all possible permutations of a string

后端 未结 30 2957
故里飘歌
故里飘歌 2020-11-22 15:10

How would I go about generating a list of all possible permutations of a string between x and y characters in length, containing a variable list of characters.

Any l

30条回答
  •  北恋
    北恋 (楼主)
    2020-11-22 15:31

    I needed this today, and although the answers already given pointed me in the right direction, they weren't quite what I wanted.

    Here's an implementation using Heap's method. The length of the array must be at least 3 and for practical considerations not be bigger than 10 or so, depending on what you want to do, patience and clock speed.

    Before you enter your loop, initialise Perm(1 To N) with the first permutation, Stack(3 To N) with zeroes*, and Level with 2**. At the end of the loop call NextPerm, which will return false when we're done.

    * VB will do that for you.

    ** You can change NextPerm a little to make this unnecessary, but it's clearer like this.

    Option Explicit
    
    Function NextPerm(Perm() As Long, Stack() As Long, Level As Long) As Boolean
    Dim N As Long
    If Level = 2 Then
        Swap Perm(1), Perm(2)
        Level = 3
    Else
        While Stack(Level) = Level - 1
            Stack(Level) = 0
            If Level = UBound(Stack) Then Exit Function
            Level = Level + 1
        Wend
        Stack(Level) = Stack(Level) + 1
        If Level And 1 Then N = 1 Else N = Stack(Level)
        Swap Perm(N), Perm(Level)
        Level = 2
    End If
    NextPerm = True
    End Function
    
    Sub Swap(A As Long, B As Long)
    A = A Xor B
    B = A Xor B
    A = A Xor B
    End Sub
    
    'This is just for testing.
    Private Sub Form_Paint()
    Const Max = 8
    Dim A(1 To Max) As Long, I As Long
    Dim S(3 To Max) As Long, J As Long
    Dim Test As New Collection, T As String
    For I = 1 To UBound(A)
        A(I) = I
    Next
    Cls
    ScaleLeft = 0
    J = 2
    Do
        If CurrentY + TextHeight("0") > ScaleHeight Then
            ScaleLeft = ScaleLeft - TextWidth(" 0 ") * (UBound(A) + 1)
            CurrentY = 0
            CurrentX = 0
        End If
        T = vbNullString
        For I = 1 To UBound(A)
            Print A(I);
            T = T & Hex(A(I))
        Next
        Print
        Test.Add Null, T
    Loop While NextPerm(A, S, J)
    J = 1
    For I = 2 To UBound(A)
        J = J * I
    Next
    If J <> Test.Count Then Stop
    End Sub
    

    Other methods are described by various authors. Knuth describes two, one gives lexical order, but is complex and slow, the other is known as the method of plain changes. Jie Gao and Dianjun Wang also wrote an interesting paper.

提交回复
热议问题