2012-03-01 105 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); 

不會使最可讀的代碼,但很有趣的寫作。 =)