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

代码中的一件显而易见的事情是 ReDim Preserve 的使用。这可能是一个相当缓慢的操作,因为我认为每次更改大小时它都会将整个数组复制到一个新数组中,并且由于您在循环内部执行此操作,因此我认为这可能是一个重要问题。

解决这个问题的最简单方法是停止使用这些类型的数组,而是使用 List 及其 Add 方法。

于 2010-04-12T18:16:58.860 回答
1

我想确保我了解您首先要做什么。你的问题似乎是:

  • 给定一个字符串列表,
  • 从列表中返回 n 项的所有可能组合,
  • 其中 n = 2 到列表的长度

例如,在 5 个字符串的列表中,您需要 2 个字符串、3 个字符串、4 个字符串和 5 个字符串的所有组合。

如果这是对您的问题的准确陈述,那么需要指出一个明显的问题。您将生成的项目数量约为 2 ^(列表长度)。这意味着无论如何尝试生成 300 个项目的所有组合都不会很快。此外,对于除最小列表之外的任何列表,您都需要懒惰地生成项目,否则您将耗尽内存。

如果您不想要所有长度的所有组合,您可能需要澄清您的问题以更好地说明您想要的目标。

于 2010-04-14T01:10:34.397 回答