我有很多短语,例如
"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表示名称列表(Nola,Leroy),node2表示动作列表(跳跃,lept),node3最终表示位置列表(悬崖,沙发)
这个想法是获取一个短语列表,并让它自动创建节点,并用短语中可以在该节点上使用的单词填充它。
那么,我将如何生成短语节点列表?我无法弄清楚如何比较两个句子,看看它们是否完全相同,减去一个单词。
第二,一旦我设置了节点,比较所有节点组合以获得新匹配的最佳方法是什么? (希望有道理)
答案 0 :(得分:5)
快速获取两个词组之间不同的词语:
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的答案。
答案 1 :(得分: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);
不能制作最易读的代码,但写作很有趣。 =)
答案 2 :(得分: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]);
}
}
}
然后当你创建你的句子时,你可以简单地遍历NodeList并从每个节点中选择一个字符串,如果你想随机做这样的话可能是这样的:
String sentence = "";
foreach (HashSet<String> Node in NodeList)
{
Random rand = new Random();
sentence += Node.ToArray()[rand.Next(0, Node.Count)];
}
如果你需要随机访问它,应该注意HashSet可能不是最佳选择。