2010-04-12 3 views
1

J'ai le code suivant pour générer des combinaisons de chaîne pour une petite liste et je voudrais l'adapter pour une grande liste de plus de 300 mots de chaîne. Peut-on suggérer comment modifier ce code ou utiliser une méthode différente.adapter le code de combinaison pour la plus grande liste

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 

'

CHANGEMENTS //

Pour wordDistance = 1 Pour 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

Pourquoi posez-vous cette question? Vous rencontrez des problèmes de performances? Ne renvoie-t-il pas les résultats attendus? –

+0

C'est un problème de performance. En fait, il a fonctionné si longtemps que j'ai dû arrêter le code car le temps cible est inférieur à une minute ou même 30 secondes si possible. Donc, par exemple, j'ai eu une liste de 335 mots de chaînes et il a fallu trop longtemps – vbNewbie

+0

En plus de ma réponse ci-dessous, il pourrait aussi y avoir des problèmes avec votre algorithme, donc si mon avis ne vaut pas la peine de le réécrire en pseudo code et le repositionner comme une question agnostique de langue qui pourrait être vu par beaucoup plus de gens (le tag VB.Net ne semble pas être si populaire ici) –

Répondre

1

Une chose évidente dans votre code est l'utilisation de ReDim Preserve . Cela peut être une opération assez lente car je pense qu'il copie l'ensemble du tableau dans un nouveau tableau chaque fois que la taille est changée, et comme vous faites cela dans les boucles, je suppose que cela pourrait être un problème important.

Le moyen le plus simple de résoudre ce problème est d'arrêter d'utiliser ces types de tableaux et d'utiliser à la place List avec sa méthode Add.

1

Je veux m'assurer de comprendre ce que vous essayez de faire en premier. Votre problème semble être:

  • Étant donné une liste de chaînes,
  • Retour chaque combinaison possible d'éléments de n dans la liste,
  • où n = 2 à la longueur de la liste

Pour Par exemple, dans une liste de 5 chaînes, vous voulez toutes les combinaisons de 2 chaînes, de 3 chaînes, de 4 chaînes et de 5 chaînes.

Si c'est une déclaration précise de votre problème, il y a un problème flagrant à signaler. Le nombre d'articles que vous allez générer est de l'ordre de 2^(longueur de la liste). Cela signifie que tenter de générer toutes les combinaisons de 300 éléments ne sera jamais rapide, peu importe quoi. En outre, pour n'importe laquelle, sauf la plus petite des listes, vous devrez générer des articles paresseusement ou vous manquerez de mémoire.

Si vous ne voulez pas toutes les combinaisons de toutes les longueurs, vous voudrez peut-être clarifier votre question pour mieux indiquer votre objectif souhaité.

+0

Merci pour la réponse. J'ai supprimé le processus redim et j'ai utilisé des listes à la place des chaînes pour réduire le temps, mais je reconnais que votre grande liste prendrait beaucoup de temps. J'ai un peu changé de code mais je suis toujours l'algorithme ci-dessus et ça marche bien mais je voudrais quand même limiter la taille et le nombre de combinaisons. Par exemple – vbNewbie

+0

si j'avais la liste de combinaison générée comme suit pour une liste de chat, chien, poule, souris: {chat, chien, poule, souris, chaton, poule, souris de poule, poule de chat, souris de poule, chat chien poule souris} :: nombre d'objets dans chaque combinaison = 4 longueur de chaque combinaison = p.ex. poule-chien = 7 espaces compris – vbNewbie

Questions connexes