2010-03-08 5 views
5

J'ai une chaîne comme "big bad dog", comment puis-je obtenir un tableau de chaînes [] qui inclut toutes les combinaisons de mots/phrases possibles? Donc, je voudrais revenir "grand", "mauvais", "chien", "grand méchant", "mauvais chien" et "grand méchant chien" - donc l'ordre des mots dans la chaîne d'origine doit être respecté.Générer un tableau de combinaison de mots dans C#

Est-ce quelque chose qui pourrait être fait avec une expression régulière?

+2

Que dire de "Big Dog"? car il préserve toujours l'ordre, mais ignore le mot du milieu. – Josh

+0

J'ai récemment fait une routine "bruteforce-like" qui le fait exaclty, mais avec des lettres. Il n'utilise pas d'expressions régulières, ou je le poste ici – Marcelo

+2

Quand vous apprenez regex, tout ressemble à un clou ... – cjk

Répondre

6

Je pense que c'est un bon problème à résoudre récursivement. Mon point de vue:

public static String[] findWords(params string[] args) 
{ 

     if (args.Count() == 0) 
     { 
      return new String[] { "" }; 
     } 
     else 
     { 
      String[] oldWords = findWords(args.Skip(1).ToArray()); 
      String[] newWords = oldWords.Where(word => word == "" || word.Split(new String[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0] == args[1]) 
             .Select(word => (args[0] + " " + word).Trim()).ToArray(); 

      return oldWords.Union(newWords).ToArray(); 
     } 
} 

A findWords("big", "bad", "dog") retourne votre liste de phrases.

Édition: Modifié pour n'inclure que des phrases consécutives.

+0

Cela résout le problème mais ne répond pas entièrement à la question OPs. –

+0

Vrai, désolé. Je promets de mieux lire dans le futur =) – Jens

+0

Merci Jens, c'est à peu près ce que je voulais. Un seul petit problème (que je n'ai pas expliqué dans mon post original) et c'est que je veux seulement des mots consécutifs ou des phrases si "gros chien" ne devrait pas être un match. Y at-il un tweak que vous pouvez faire à votre code? – Stuart

6
string[] array = new string[]{"big", "bad", "dog"}; 
for(ulong mask = 0; mask < (1ul << array.Length); mask++) 
{ 
    string permutation = ""; 
    for(int i = 0; i < array.Length; i++) 
    { 
     if((mask & (1ul << (array.Length - 1 - i))) != 0) 
     { 
      permutation += array[i] + " "; 
     } 
    } 
    Console.WriteLine(permutation); 
} 

EDIT: Non, cela ne peut pas être fait en utilisant une seule expression régulière.

EDIT: Pour Eric Lippert, remplacez les masques par ulong (UInt64).

+0

Cela résout le problème mais ne répond pas entièrement à la question OPs. –

+3

Et s'il y a plus de 32 mots? (Je sais, il faudra un certain temps pour passer à travers les quatre premiers milliards, mais les machines sont rapides ces jours-ci.) –

0

Qu'en est-il divise la chaîne en tableau de mots séparés

string str = "big fat dog"; 
string[] words = str.Split(new Char[] { ' ', ',', '.', ':', '\t' }); 

et vous pouvez l'utiliser pour faire des combinaisons de mots

string[] words = new string[]{"big", "bad", "dog"}; 
for(int mask = 0; mask < 1 << (words.Length); mask++) 
{ 
    string permutation = ""; 
    for(int i = 0; i < words.Length; i++) 
    { 
    if((mask & (1 << (words.Length - 1 - i))) != 0) 
    { 
     permutation += words[i] + " "; 
    } 
    } 
    Console.WriteLine(permutation); 
} 

Je pense que expresion régulière n'a pas d'usage ici .

+0

Cela résout le problème, mais ne répond pas entièrement à la question OPs. –

+0

Ce n'est pas? S'il vous plaît, puis-je le laisser comme ça, madame? – Machta

Questions connexes