VBA Excel中的排列

时间:2015-03-16 13:44:15

标签: excel algorithm vba permutation combinatorics

我正在尝试生成一组字符的所有可能组合。输入数组具有n个字符,5< = n< = 7,并且我想生成包含所有C(n,5)组合的第二阵列A(C(n,5),5)。数组中字符的顺序并不重要。

这是一个例子: 输入数组:{A,B,C,D,E,F},所以n = 6 输出数组应该是:

{A B C D E},
{A B C D F},
{A B C F E},
{A B F D E},
{A F C D E},
{F B C D E},

对于n = 5和n = 6,这非常简单,但是对于n = 7,这变得非常复杂。有谁知道我该怎么做?

由于

3 个答案:

答案 0 :(得分:0)

递归解决。

例如,您的n = 7案例。在外层,您从{A,B,C,D,E,F,G}开始。从这里,你拿出一封信;一个不同的7次。所以你在这个输出数组中有7个元素,每个元素有6个字母:{A,B,C,D,E,F},{A,B,C,D,E,G}等。

对于这些输出的每个,您可以进一步减少使用相同的算法。你已经知道如何处理{A,B,C,D,E,F}。

答案 1 :(得分:0)

这只是 Bathsheba的建议的实现,并将生成所有 5-of-7 的所有内容。首先在标准模块中插入以下 UDF

Public Function DropCH(sIn As String, L As Long) As String
    If L = 1 Then
        DropCH = Mid(sIn, 2)
        Exit Function
    End If

    ll = Len(sIn)
    If ll = L Then
        DropCH = Left(sIn, L - 1)
        Exit Function
    End If

    If L > ll Then
        DropCH = ""
        Exit Function
    End If
    DropCH = Mid(sIn, 1, L - 1) & Mid(sIn, L + 1)
End Function

然后将7个字符串放在 A1 中。然后在 C1 中输入:

=DropCH($A$1,COLUMNS($A:A))

并通过 I1 C1 复制到 D1

C2 中输入:

=DropCH(C$1,ROW()-1)

并从 D2 复制 C2 I2

然后删除重复项运行此宏:

Sub DropDuplicates()
    Dim c As Collection, K As Long
    Set c = New Collection
    On Error Resume Next
    K = 1

    For Each r In Range("C2:I7")
        If r.Value <> "" Then
            c.Add r.Value, CStr(r.Value)
            If Err.Number = 0 Then
                Cells(K, "J").Value = r.Value
                K = K + 1
            Else
                Err.Number = 0
            End If
        End If
    Next r
    On Error GoTo 0
End Sub

这会将结果放在 J

列中

enter image description here

答案 2 :(得分:0)

刚刚找到一种方法来递归并避免双重结果。代码非常难看,因为我没有时间考虑如何在这里使用循环。

Public Function Permutacao(card1 As String,card2 As String,card3 As String,card4 As String,card5 As String,可选card6 As String,可选card7 As String)

Dim A(1 To 7) As String
Dim aux_A(1 To 7, 1 To 6) As String
Dim aux2_A(1 To 6, 1 To 5) As String
Dim final_A(1 To 42, 1 To 6) As String

n = 5

A(1) = card1
A(2) = card2
A(3) = card3
A(4) = card4
A(5) = card5


If Not IsMissing(card6) Then
    A(6) = card6
    n = 6
End If
If Not IsMissing(card7) Then
    A(7) = card7
    n = 7
End If

If n = 5 Then

    final_A(1, 1) = A(1)
    final_A(1, 2) = A(2)
    final_A(1, 3) = A(3)
    final_A(1, 4) = A(4)
    final_A(1, 5) = A(5)

ElseIf n = 6 Then

    k = 1
    final_A(k, 1) = A(1)
    final_A(k, 2) = A(2)
    final_A(k, 3) = A(3)
    final_A(k, 4) = A(4)
    final_A(k, 5) = A(5)

    k = 2

    final_A(k, 1) = A(1)
    final_A(k, 2) = A(2)
    final_A(k, 3) = A(3)
    final_A(k, 4) = A(4)
    final_A(k, 5) = A(6)

    k = 3

    final_A(k, 1) = A(1)
    final_A(k, 2) = A(2)
    final_A(k, 3) = A(3)
    final_A(k, 4) = A(6)
    final_A(k, 5) = A(5)

    k = 4

    final_A(k, 1) = A(1)
    final_A(k, 2) = A(2)
    final_A(k, 3) = A(6)
    final_A(k, 4) = A(4)
    final_A(k, 5) = A(5)

    k = 5

    final_A(k, 1) = A(1)
    final_A(k, 2) = A(6)
    final_A(k, 3) = A(3)
    final_A(k, 4) = A(4)
    final_A(k, 5) = A(5)

    k = 6

    final_A(k, 1) = A(6)
    final_A(k, 2) = A(2)
    final_A(k, 3) = A(3)
    final_A(k, 4) = A(4)
    final_A(k, 5) = A(5)

ElseIf n = 7 Then

    k = 1
    aux_A(k, 1) = A(1)
    aux_A(k, 2) = A(2)
    aux_A(k, 3) = A(3)
    aux_A(k, 4) = A(4)
    aux_A(k, 5) = A(5)
    aux_A(k, 6) = A(6)

    k = 2
    aux_A(k, 1) = A(1)
    aux_A(k, 2) = A(2)
    aux_A(k, 3) = A(3)
    aux_A(k, 4) = A(4)
    aux_A(k, 5) = A(5)
    aux_A(k, 6) = A(7)

    k = 3
    aux_A(k, 1) = A(1)
    aux_A(k, 2) = A(2)
    aux_A(k, 3) = A(3)
    aux_A(k, 4) = A(4)
    aux_A(k, 5) = A(7)
    aux_A(k, 6) = A(6)

    k = 4
    aux_A(k, 1) = A(1)
    aux_A(k, 2) = A(2)
    aux_A(k, 3) = A(3)
    aux_A(k, 4) = A(7)
    aux_A(k, 5) = A(5)
    aux_A(k, 6) = A(6)

    k = 5
    aux_A(k, 1) = A(1)
    aux_A(k, 2) = A(2)
    aux_A(k, 3) = A(7)
    aux_A(k, 4) = A(4)
    aux_A(k, 5) = A(5)
    aux_A(k, 6) = A(6)

    k = 6
    aux_A(k, 1) = A(1)
    aux_A(k, 2) = A(7)
    aux_A(k, 3) = A(3)
    aux_A(k, 4) = A(4)
    aux_A(k, 5) = A(5)
    aux_A(k, 6) = A(6)

    k = 7
    aux_A(k, 1) = A(7)
    aux_A(k, 2) = A(2)
    aux_A(k, 3) = A(3)
    aux_A(k, 4) = A(4)
    aux_A(k, 5) = A(5)
    aux_A(k, 6) = A(6)

    c = 1

    k = 1

    While k <= 7

        If k < 2 Then
            final_A(c, 1) = aux_A(k, 1)
            final_A(c, 2) = aux_A(k, 2)
            final_A(c, 3) = aux_A(k, 3)
            final_A(c, 4) = aux_A(k, 4)
            final_A(c, 5) = aux_A(k, 5)

            c = c + 1

        End If

        If k < 3 Then


            final_A(c, 1) = aux_A(k, 1)
            final_A(c, 2) = aux_A(k, 2)
            final_A(c, 3) = aux_A(k, 3)
            final_A(c, 4) = aux_A(k, 4)
            final_A(c, 5) = aux_A(k, 6)

            c = c + 1

        End If

        If k < 4 Then

            final_A(c, 1) = aux_A(k, 1)
            final_A(c, 2) = aux_A(k, 2)
            final_A(c, 3) = aux_A(k, 3)
            final_A(c, 4) = aux_A(k, 6)
            final_A(c, 5) = aux_A(k, 5)

            c = c + 1
        End If

        If k < 5 Then

            final_A(c, 1) = aux_A(k, 1)
            final_A(c, 2) = aux_A(k, 2)
            final_A(c, 3) = aux_A(k, 6)
            final_A(c, 4) = aux_A(k, 4)
            final_A(c, 5) = aux_A(k, 5)

            c = c + 1
        End If

        If k < 6 Then

            final_A(c, 1) = aux_A(k, 1)
            final_A(c, 2) = aux_A(k, 6)
            final_A(c, 3) = aux_A(k, 3)
            final_A(c, 4) = aux_A(k, 4)
            final_A(c, 5) = aux_A(k, 5)

            c = c + 1
        End If

        If k < 7 Then

            final_A(c, 1) = aux_A(k, 6)
            final_A(c, 2) = aux_A(k, 2)
            final_A(c, 3) = aux_A(k, 3)
            final_A(c, 4) = aux_A(k, 4)
            final_A(c, 5) = aux_A(k, 5)

            c = c + 1

        End If

        k = k + 1

    Wend


End If

Permutacao = final_A

结束功能