簡體   English   中英

VBA Excel 中的排列

[英]Permutations in VBA Excel

我正在嘗試生成字符數組的所有可能組合。 輸入數組有 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 就變得非常復雜。 有誰知道我應該怎么做這個?

謝謝

遞歸解決。

例如,您的 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}。

這只是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))

並通過I1C1復制到D1

C2 中輸入:

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

並將C2D2復制到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列中

在此處輸入圖片說明

剛剛找到了一種遞歸方式並避免雙重結果的方法。 代碼非常難看,因為我沒有時間考慮如何在這里使用循環。

Public Function Permutacao(card1 As String, card2 As String, card3 As String, card4 As String, card5 As String, Optional card6 As String, Optional 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
End Function

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM