комбинации слов в массивах (или в многомерном массиве) - PullRequest
0 голосов
/ 31 августа 2018

У меня есть следующий массив:

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, и не могу понять, как это обойти.

Какой самый лучший / быстрый способ решить эту проблему?

Спасибо заранее

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

ОП указывается после декартового произведения . Как подсказывает @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 
0 голосов
/ 31 августа 2018

Просто сохраните список всех последовательностей, которые вы уже сделали, и просто добавьте новую ко всем предыдущим последовательностям.

    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

Переменная allPossabilities - это ваш массив. Я решил использовать список, чтобы мне было легче. Использование (,) не будет предлагать те же опции, что и использование () ().

        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")
...