数组中的单词组合(或多维数组中的单词组合)

问题描述 投票:1回答:2

我有以下数组:

array1(0,0) = "aaa "
array1(0,1) = "bbb "
array1(0,2) = "ccc "

array1(1,0) = "ddd "
array1(1,1) = "eee "

array1(2,0) = "fff "
array1(2,1) = "ggg "

我想获得以下所有可能的组合:

aaa ddd fff
aaa ddd ggg
aaa eee fff
aaa eee ggg

bbb ddd fff
bbb ddd ggg
bbb eee fff
bbb eee ggg

ccc ddd fff
ccc ddd ggg
ccc eee fff
ccc eee ggg

数组的长度在两个维度都是动态的,不仅在第二个维度中,因此在其中不包含3个For循环的解决方案。我正在用VB工作,而且我无法看到如何解决这个问题的方法。

哪种解决方案最好/最快?

谢谢你提前

vb.net combinations combinatorics
2个回答
0
投票

OP是在Cartesian product之后。正如@the_lotus建议的那样,OP应该在这里使用List,因为你将对给定维度中每个级别的长度进行更严格的控制。因为它与阵列一致,我们必须做一些循环体操来找到每个级别的长度。

这是一种生成蝎子产品同时避免产生中间体的算法(例如,"aaa ""aaa ddd "等)

Dim array1(0 To 2, 0 To 2) As String, i As Long, j As Long
Dim myProd As Long, sizeDim() As Long, loopLim As Long, test As Long
Dim lenArr As Long, myCounter() As Long, myComb As String

array1(0, 0) = "aaa "
array1(0, 1) = "bbb "
array1(0, 2) = "ccc "

array1(1, 0) = "ddd "
array1(1, 1) = "eee "

array1(2, 0) = "fff "
array1(2, 1) = "ggg "

lenArr = UBound(array1, 1)
myProd = 1
ReDim sizeDim(0 To lenArr)

For j = 0 To lenArr
    test = UBound(array1, 2)

    '' Find the last non-empty entry
    Do While Len(array1(j, test) & vbNullString) = 0
        test = test - 1
    Loop

    myProd = myProd * (test + 1)
    sizeDim(j) = test
Next j

ReDim myCounter(0 To lenArr)
loopLim = myProd - 1
myComb = vbNullString

Dim cartProd() as String
Redim cartProd(0 to loopLim)

For i = 0 To loopLim - 1
    For j = 0 To lenArr
        myComb = myComb & array1(j, myCounter(j))
    Next j

    cartProd(i) = myComb
    Console.Writeline(myComb)

    test = 0
    Do While (myCounter(test) = sizeDim(test))
        myCounter(test) = 0
        test = test + 1
    Loop

    myCounter(test) = myCounter(test) + 1
    myComb = vbNullString
Next i

'' Get last result
For j = 0 To lenArr
    myComb = myComb & array1(j, myCounter(j))
Next j

cartProd(loopLim) = myComb
Console.Writeline(myComb)

这是输出:

aaa ddd fff 
bbb ddd fff 
ccc ddd fff 
aaa eee fff 
bbb eee fff 
ccc eee fff 
aaa ddd ggg 
bbb ddd ggg 
ccc ddd ggg 
aaa eee ggg 
bbb eee ggg 
ccc eee ggg 

1
投票

只需保留已经完成的所有序列的列表,然后将新序列添加到所有先前序列中。

    Dim allSequences As New List(Of String)

    allSequences.Add("")

    For x As Integer = 0 To allPossibilities.Count - 1
        Dim newSequences As New List(Of String)

        For y As Integer = 0 To allPossibilities(x).Count - 1
            For Each s As String In allSequences
                newSequences.Add(s & allPossibilities(x)(y))
            Next
        Next

        allSequences = newSequences
    Next

变量allPossibilities是你的数组。我决定使用一个列表让我更容易。使用(,)不会提供与using()()相同的选项。

        Dim allPossibilities As New List(Of List(Of String))

        allPossibilities.Add(New List(Of String))
        allPossibilities(0).Add("aaa")
        allPossibilities(0).Add("bbb")
        allPossibilities(0).Add("ccc")

        allPossibilities.Add(New List(Of String))
        allPossibilities(1).Add("ddd")
        allPossibilities(1).Add("eee")

        allPossibilities.Add(New List(Of String))
        allPossibilities(2).Add("fff")
        allPossibilities(2).Add("ggg")
© www.soinside.com 2019 - 2024. All rights reserved.