1

小さなリストの文字列の組み合わせを生成する次のコードがあり、これを 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
4

2 に答える 2

1

最初に何をしようとしているのかを理解したいと思います。あなたの問題は次のようです:

  • 文字列のリストが与えられると、
  • リストから n 個のアイテムのすべての可能な組み合わせを返します。
  • ここで、n = 2 からリストの長さ

たとえば、5 つの文字列のリストでは、2 つの文字列、3 つの文字列、4 つの文字列、および 5 つの文字列のすべての組み合わせが必要です。

それが問題の正確な説明である場合、指摘すべき明白な問題が 1 つあります。生成する項目の数は 2 ^ (リストの長さ) のオーダーです。これは、300 個のアイテムのすべての組み合わせを生成しようとしても、決して高速ではないことを意味します。また、最も小さなリスト以外の場合は、アイテムを遅延して生成する必要があります。そうしないと、メモリが不足します。

すべての長さのすべての組み合わせが必要ない場合は、質問を明確にして、希望する目標をより適切に述べることができます。

于 2010-04-14T01:10:34.397 に答える
1

コードで明らかなことの 1 つは、ReDim Preserve の使用です。サイズが変更されるたびに配列全体を新しい配列にコピーすると思うので、これは非常に遅い操作になる可能性があります。ループ内でそれを行っているため、これは重大な問題になる可能性があると思います。

これを修正する最も簡単な方法は、これらの種類の配列の使用をやめ、代わりに Add メソッドで List を使用することです。

于 2010-04-12T18:16:58.860 に答える