2010-03-08 98 views
5

Tengo una cadena como "big bad dog", ¿cómo puedo obtener una matriz de cadenas [] que incluya todas las posibles combinaciones de palabras y frases?Generar conjunto de combinaciones de palabras en C#

Entonces, me gustaría volver "grande", "malo", "perro", "grande malo", "perro malo" y "perro malo grande" - por lo tanto, el orden de las palabras en la secuencia original debe ser respetado.

¿Esto es algo que podría hacerse con una expresión regular?

+2

¿Qué hay de "Big Dog"? ya que aún conserva el orden, pero ignora la palabra del medio. – Josh

+0

Hace poco hice una rutina de "fuerza bruta" que sí lo hace, pero con letras. No usa expresiones regulares, o lo publicaría aquí – Marcelo

+2

Cuando aprendes regex, todo parece un clavo ... – cjk

Respuesta

6

Creo que este es un buen problema para resolver recursivamente. Mi opinión:

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(); 
     } 
} 

Un findWords("big", "bad", "dog") devuelve la lista de frases.

Editar: Editado para incluir solo frases consecutivas.

+0

Esto resuelve el problema pero no responde completamente la pregunta de OP. –

+0

Es cierto, lo siento. Prometo leer mejor en el futuro =) – Jens

+0

Gracias Jens, esto es más o menos lo que quería. Solo un pequeño problema (que no expliqué en mi publicación original) y es que solo quiero palabras o frases consecutivas para que "perro grande" no coincida. ¿Hay alguna modificación que pueda hacer en su código? – 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); 
} 

EDITAR: No, no se puede hacer utilizando solo una expresión regular.

EDITAR: Per Eric Lippert, cambiar las máscaras a ulong (UInt64).

+0

Esto resuelve el problema pero no responde completamente la pregunta de OP. –

+3

¿Y qué pasa si hay más de 32 palabras? (Lo sé, tomará un tiempo para pasar los primeros cuatro mil millones, pero las máquinas son rápidas en estos días.) –

0

¿Qué pasa con la división de la cadena en serie de palabras separadas

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

y luego se pueden utilizar esto para hacer combinaciones de palabras

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); 
} 

que pensar expresion regular tiene ninguna utilidad aquí .

+0

Esto resuelve el problema pero no responde completamente la pregunta de OP. –

+0

No? Por favor, ¿puedo dejarlo así, señora profesora? – Machta

Cuestiones relacionadas