адаптация кода комбинации для большего списка - PullRequest
1 голос
/ 12 апреля 2010

У меня есть следующий код для генерации комбинаций строк для небольшого списка, и я хотел бы адаптировать его для большого списка из более чем 300 строковых слов. Кто-нибудь может подсказать, как изменить этот код или использовать другой метод.

Public Class combinations



Public Shared Sub main()

    Dim myAnimals As String = "cat dog horse ape hen mouse"

    Dim myAnimalCombinations As String() = BuildCombinations(myAnimals)

    For Each combination As String In myAnimalCombinations
        ''//Look on the Output Tab for the results! 
        Console.WriteLine("(" & combination & ")")
    Next combination

    Console.ReadLine()

End Sub



Public Shared Function BuildCombinations(ByVal inputString As String) As String()

    ''//Separate the sentence into useable words. 
    Dim wordsArray As String() = inputString.Split(" ".ToCharArray)

    ''//A plase to store the results as we build them 
    Dim returnArray() As String = New String() {""}

    ''//The 'combination level' that we're up to 
    Dim wordDistance As Integer = 1

    ''//Go through all the combination levels... 
    For wordDistance = 1 To wordsArray.GetUpperBound(0)

        ''//Go through all the words at this combination level... 
        For wordIndex As Integer = 0 To wordsArray.GetUpperBound(0) - wordDistance

            ''//Get the first word of this combination level 
            Dim combination As New System.Text.StringBuilder(wordsArray(wordIndex))

            ''//And all all the remaining words a this combination level 
            For combinationIndex As Integer = 1 To wordDistance

                combination.Append(" " & wordsArray(wordIndex + combinationIndex))

            Next combinationIndex

            ''//Add this combination to the results 
            returnArray(returnArray.GetUpperBound(0)) = combination.ToString

            ''//Add a new row to the results, ready for the next combination 
            ReDim Preserve returnArray(returnArray.GetUpperBound(0) + 1)

        Next wordIndex

    Next wordDistance

    ''//Get rid of the last, blank row. 
    ReDim Preserve returnArray(returnArray.GetUpperBound(0) - 1)

    ''//Return combinations to the calling method. 
    Return returnArray

End Function

End Class

МЕНЯЕТ //

Для wordDistance = 1 Для inputList.Count.ToString / 2

        Dim count = inputList.Count.ToString

        'Go through all the words at this combination level... 
        For wordIndex As Integer = 0 To inputList.Count.ToString - wordDistance

            'Get the first word of this combination level 
            combination.Add(inputList.Item(wordIndex))
            'And all all the remaining words a this combination level 
            For combinationIndex As Integer = 1 To wordDistance
                combination.Add(" " & inputList.Item(wordIndex + combinationIndex))
            Next combinationIndex

            'Add this combination to the results 

            If Not wordsList.Contains(combination) Then
                wordsList.Add(combination.ToString)
            End If

            'Add a new row to the results, ready for the next combination 
            'ReDim Preserve returnArray(returnArray.GetUpperBound(0) + 1)

        Next wordIndex

    Next wordDistance

Ответы [ 2 ]

1 голос
/ 14 апреля 2010

Я хочу убедиться, что я понимаю, что вы пытаетесь сделать в первую очередь. Кажется, ваша проблема:

  • Учитывая список строк,
  • Вернуть каждую возможную комбинацию из n элементов из списка,
  • где n = 2 к длине списка

Например, в списке из 5 строк вам понадобятся все комбинации из 2 строк, из 3 строк, из 4 строк и из 5 строк.

Если это точное изложение вашей проблемы, следует указать на одну явную проблему. Количество предметов, которые вы будете генерировать, составляет порядка 2 ^ (длина списка). Это означает, что попытка сгенерировать все комбинации из 300 предметов никогда не будет быстрой, несмотря ни на что. Кроме того, для любого, кроме самых маленьких списков, вам нужно будет генерировать элементы лениво, или у вас не хватит памяти.

Если вам не нужны все комбинации всех длин, вы можете уточнить свой вопрос, чтобы лучше сформулировать желаемую цель.

1 голос
/ 12 апреля 2010

Одна очевидная вещь в вашем коде - это использование ReDim Preserve. Это может быть довольно медленной операцией, поскольку я думаю, что она копирует весь массив в новый массив каждый раз, когда изменяется размер, и, поскольку вы делаете это внутри циклов, я предполагаю, что это может быть существенной проблемой.

Самый простой способ исправить это прекратить использование таких массивов и вместо этого использовать List с его методом Add.

...