2010-04-12 33 views
1

我有以下代码来生成一个小列表的字符串的组合,并希望适应这个超过300个字符串words.Can任何人都可以建议如何改变此代码或使用一种不同的方法。适应组合代码大列表

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 

'

CHANGES //

对于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 
+0

你为什么问这个问题?您是否遇到性能问题?它不会返回预期的结果吗? – 2010-04-12 15:23:48

+0

这是一个性能问题。事实上,它的运行时间很长,我不得不停止代码,因为如果可能的话,目标时间不到一分钟甚至30秒。因此,例如,我有一个335字符串单词列表,它只是花了很长时间 – vbNewbie 2010-04-12 15:37:05

+0

除了我的答案下面,也可能有您的算法的问题,所以如果我的建议并不能帮助它可能值得重写它作为伪代码并将其重新设置为一个语言不可知的问题,可能会被很多人看到(VB.Net标记在这里似乎并不受欢迎) – 2010-04-12 18:18:00

回答

1

一个明显的一点是使用ReDim的使用保留。这可能是一个相当缓慢的操作,因为我认为每次大小改变时它会将整个数组复制到一个新数组中,并且由于您在循环内执行此操作,因此我认为这可能是一个重大问题。

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

1

我想确保我明白你想要先做什么。你的问题似乎是:

  • 给出一个字符串列表,
  • 返回从列表n个项目每个可能的组合,
  • 其中n = 2至清单

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

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

如果你不想要所有长度的所有组合,你可能想澄清你的问题,以更好地表达你想要的目标。

+0

感谢您的回应。我删除了Redim进程,并使用了ArrayList而不是字符串来减少一些时间,但我确实承认你的观点,即大型列表需要花费大量时间。我改变了一下代码,但仍然遵循上面的算法,它工作正常,但我仍然想限制组合的大小和数量。例如 – vbNewbie 2010-04-15 17:54:50

+0

如果我为猫,狗,母鸡,小鼠列表产生如下组合列表:{猫,狗,母鸡,小鼠,猫狗,狗母鸡,母鸡鼠,猫狗母鸡,狗母鸡鼠标,猫狗母鸡鼠标} ::每种组合中物品的数量= 4 每种组合的长度=例如狗母鸡= 7包括空格 – vbNewbie 2010-04-15 17:55:51