2012-03-01 103 views
5

我有短语,如查找两个字符串

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

我需要找到一个短语,是一个不同的单词每个点和该单词添加到一个节点,这是一个大名单之间不同的字可以在短语中用于该位置的单词列表。所以我们最终会结束。

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

当节点1代表名称(诺拉,乐华)的列表,节点2表示动作的列表(跳下,lept)和节点3最终表示的位置列表(悬崖,沙发)

这个想法是获取这些短语的列表,并让它自动创建节点并用短语中可以在该节点中使用的单词填充它。

那么,1st我将如何生成短语节点的列表?我一直无法弄清楚如何比较两个句子,看他们是否完全一样,减去一个词。

第二次,我有节点的设置,比较所有的节点组合来提出新的匹配的最佳方法是什么? (希望是有道理的)

+0

“我需要找到一个词是不同的单词中的每个点” - 不同于**什么**? – Gangnus 2012-03-01 20:10:14

+0

您可以使用string.Split()将每个字符串拆分为一个字符串[],并将该空格用作分隔符。然后比较结果数组中的每个字符串。 – Khan 2012-03-01 20:11:27

+0

您可以为句子中的每个单词位置创建“节点列表”,遍历所有样本并收集节点。然后你可以折叠所有只包含一个单词的节点(在你的情况下,节点位置3和4)。 – dasblinkenlight 2012-03-01 20:11:57

回答

5

不错,我喜欢它。既然你用C#标记了你的问题,我也用C#写了答案。

快速的方式来获得两个短语之间的不同的词:

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

而是通过遍历和检查每个元素自己的元素相匹配的,你可以节省自己的时间,并使用内置的LINQ函数Intersect,Except等...

要随机创建短语,请参阅NominSim的答案。

+0

我从来没有见过相交,这是一件漂亮的事情。 – SpectralEdge 2012-03-01 21:02:36

+0

对不起,这花了我很长时间才选择正确的答案,我被一个新项目所左右,刚回到这个项目。 – SpectralEdge 2012-03-19 07:51:34

0

首先生成列表这样的事情应该工作:

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

然后,当你创建你的句子,你可以简单地遍历节点列表,并从每个节点选择一个字符串,如果你要做到这一点,也许随机像这样:

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

应该注意,HashSet的可能不是最好的主意,如果你需要随机访问。

1

另一个基于LINQ的解决方案产生的所有可能的组合:

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

不会使最可读的代码,但很有趣的写作。 =)