2012-03-01 8 views
5

que tengo una larga lista de frases tales comoEncuentra palabra diferente entre dos cadenas

"Nola jumped off the cliff" 
"Loroy jumped off the cliff" 
"Nola jumped off the couch" 
"Leroy lept off the couch" 

Necesito encontrar cada punto en una frase que es una palabra diferente y añadir esa palabra a un nodo, que es una lista de palabras que se pueden usar en esa posición en una frase. Entonces terminaríamos con.

"Node1(1) Node2(1) off the Node3(1)" 
"Node1(2) Node2(1) off the Node3(1)" 
...etc 

Dónde nodo 1 representa una lista de los nombres (Nola, Leroy), node2 representa una lista de las acciones (saltado, lept) y node3 termina en representación de la lista de lugares (acantilado, sofá)

La idea es tomar una lista de frases y hacer que cree automáticamente los nodos y llenarlos con las palabras que se pueden usar en ese nodo en una frase.

Entonces, primero ¿cómo generaría la lista de nodos de frase? No he podido averiguar cómo comparar dos oraciones y ver si son exactamente iguales menos una palabra.

2nd una vez que tengo los nodos configurados, ¿cuál sería la mejor manera de comparar todas las combinaciones de los nodos para obtener nuevas coincidencias? (Esperanza de que tenía sentido)

+0

"Necesito encontrar cada punto en una frase que sea una palabra diferente" - ¿diferente de ** qué **? – Gangnus

+0

Puede dividir cada cadena en una cadena [] usando string.Split() y usar el espacio como delimitador. Luego compara cada cadena en las matrices resultantes. – Khan

+0

Puede crear "listas de nodos" para cada posición de palabra en una oración, recorrer todas las muestras y recopilar sus nodos. Entonces podría colapsar todos los nodos que contienen solo una palabra (en su caso, los nodos en la posición 3 y 4). – dasblinkenlight

Respuesta

5

Bueno, me gusta. Como etiquetó su pregunta con C#, escribí la respuesta también en C#.

Una manera rápida de conseguir las diferentes palabras entre dos frases:

string phrase1 = "Nola jumped off the cliff"; 
string phrase2 = "Juri jumped off the coach"; 

//Split phrases into word arrays 
var phrase1Words = phrase1.Split(' '); 
var phrase2Words = phrase2.Split(' '); 

//Find the intersection of the two arrays (find the matching words) 
var wordsInPhrase1and2 = phrase1Words.Intersect(phrase2Words); 

//The number of words that differ 
int wordDelta = phrase1Words.Count() - wordsInPhrase1and2.Count(); 

//Find the differing words 
var wordsOnlyInPhrase1 = phrase1Words.Except(wordsInPhrase1and2); 
var wordsOnlyInPhrase2 = phrase2Words.Except(wordsInPhrase1and2); 

En lugar de hacer coincidir los elementos usted mismo haciendo un bucle en una y la comprobación de cada elemento, se puede ahorrar tiempo y utilizar el built-in Funciones de LINQ Intersecar, Excepto, etc ...

Para crear frases de forma aleatoria, consulte la respuesta de NominSim.

+0

Nunca antes había visto intersección, esto es algo ingenioso. – SpectralEdge

+0

Lo siento, esto me tomó tanto tiempo para seleccionar como la respuesta correcta, me desvió de un nuevo proyecto y volví a este. – SpectralEdge

0

Primero para generar la lista algo como esto debería funcionar:

 HashSet<String>[] NodeList = new HashSet<String>[phraseLength]; 
     for (int i = 0; i < phraseLength; i++) 
     { 
      NodeList[i] = new HashSet<string>(); 
     } 

     foreach (String phrase in PhraseList) 
     { 
      string[] phraseStrings = phrase.Split(' '); 
      for (int i = 0; i < phraseLength; i++) 
      { 
       if(!NodeList[i].Contains(phraseStrings[i])) 
       { 
        NodeList[i].Add(phraseStrings[i]); 
       } 
      } 
     } 

continuación, cuando cree sus frases sólo tiene que atravesar el NodeList y recoger una cadena de cada nodo, si quería hacerlo al azar tal vez algo como esto:

 String sentence = ""; 
     foreach (HashSet<String> Node in NodeList) 
     { 
      Random rand = new Random(); 
      sentence += Node.ToArray()[rand.Next(0, Node.Count)]; 
     } 

deben tener en cuenta que un HashSet probablemente no es la mejor idea si necesita acceder a él de forma aleatoria.

1

Sin embargo, otra solución basada en LINQ que genera todas las combinaciones posibles:

var phrases = new List<string> { 
      "Nola jumped off the cliff", 
      "Loroy jumped off the cliff", 
      "Nola jumped off the couch", 
      "Leroy lept off the couch" 
          }; 

var sets = (from p in phrases 
      from indexedWord in p.Split(' ').Select((word,idx) => new {idx,word}) 
      group indexedWord by indexedWord.idx into g 
      select g.Select(e => e.word).Distinct()).ToArray(); 


var allCombos = from w1 in sets[0] 
       from w2 in sets[1] 
       from w3 in sets[2] 
       from w4 in sets[3] 
       from w5 in sets[4] 
       select String.Format("{0} {1} {2} {3} {4}.", w1, w2, w3, w4, w5); 

no hace el código más legible, pero fue muy divertido escribir. =)

Cuestiones relacionadas