想象一下,我们手头有一些参考文本
四年前和七年前,我们的父亲提出了这个问题 大陆一个新的国家,在自由中孕育,并致力于 所有人都是平等的主张。现在我们正在搞一个 伟大的内战,无论是对那个民族,还是任何国家,都在考验 构思和如此专注,可以长久忍受。我们遇到了一个伟大的 那场战争的战场。我们已经致力于其中的一部分 田野,作为在这里献出生命的人的最后安息之所 那个国家可能会生活。这完全合适 我们应该这样做。但是,从更广泛的意义上说,我们不能奉献,我们可以 没有奉献,我们不能让这个理由成为现实。勇敢的人,活着 在这里挣扎的死者已经将它奉献给了我们,远远超过了我们的穷人 增加或减少的力量。世界将很少注意到,也不会长久记住 我们在这里说的是什么,但它永远不会忘记他们在这里做了什么。它是 对我们来说,生活,而是在这里献给未完成的工作 到目前为止,他们在这里战斗的人如此高尚。它是 而是让我们在这里致力于以前的伟大任务 我们 - 从这些光荣的死者那里,我们更加热爱这一点 他们给出了最后一个充分的奉献精神的原因 - 我们 在这里高度决心,这些死者不会白白死去 在上帝之下,这个国家将有一个新的自由诞生 - 那个 人民政府,人民政府,人民政府,不应该 从地球上消失。
我们收到该文字的片段给我们,没有空格或标点,有些字符被删除,插入和替换
ieldasafinalrTstingplaceforwhofoughtheregavetheirliZesthatthatn
使用参考文本我们可以使用什么工具(使用任何编程语言)来正确地区分单词
ield as a final rTsting place for who fought here gave their liZes that that n
不需要纠正错误,只需间隔
答案 0 :(得分:1)
你遇到了奇怪的问题:)
如果您不能依赖大写提示,只需将所有内容小写为开头。
然后获取单词词典。也许只需wordlist,或者您可以尝试Wordnet。
和类似,正确间隔的材料的语料库。如果合适,请下载Wikipedia dump。你需要清理它并打入ngrams。 3克可能适合这项任务。或者节省时间并使用Google的ngram数据。 web ngrams(付费)或book ngrams(免费)。
设置最大字长。让我们说20chars。
获取神秘字符串的第一个字符,并在字典中查找。然后拿前2个字符查找它们。继续这样做直到你到达20.存储你得到的所有匹配,但最长的匹配可能是最好的。通过字符串一次移动起始点1个字符。
你最终会得到一系列有效的单词匹配。
循环遍历此新数组,并将每个值与以下值配对,并将其与原始字符串进行比较,以便识别所有可能不重叠的有效单词组合。您可能最终得到1个输出字符串,或几个。
如果你有几个,将每个输出字符串分成3克。然后在新的ngram数据库中查找以查看最常见的组合。
可能还有一些节省时间的技巧,例如从停用词开始,在字典中检查它们并在左侧添加增量字母,然后在那里添加空格。
......或者我对整个问题感到不满,并且有一个人会谦卑我的一个班轮:)
答案 1 :(得分:1)
您可以使用编辑距离并查找参考的最小编辑距离子字符串来执行此操作。在这里查看我的答案(PHP实现)到类似的问题:
Longest Common Substring with wrong character tolerance
使用上面链接中的shortest_edit_substring()
函数,您可以在删除除字母之外的所有内容(或任何您想要保留的内容:字母,数字等)之后添加此功能以进行搜索,然后正确映射结果回到原始版本。
// map a stripped down substring back to the original version
function map_substring($haystack_letters,$start,$length,$haystack, $regexp)
{
$r_haystack = str_split($haystack);
$r_haystack_letters = $r_haystack;
foreach($r_haystack as $k => $l)
{
if (preg_match($regexp,$l))
{
unset($r_haystack_letters[$k]);
}
}
$key_map = array_keys($r_haystack_letters);
$real_start = $key_map[$start];
$real_end = $key_map[$start+$length-1];
$real_length = $real_end - $real_start + 1;
return array($real_start,$real_length);
}
$haystack = 'Four score and seven years ago our fathers brought forth on this continent a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation, so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we can not dedicate, we can not consecrate, we can not hallow this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us—that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion—that we here highly resolve that these dead shall not have died in vain—that this nation, under God, shall have a new birth of freedom—and that government of the people, by the people, for the people, shall not perish from the earth.';
$needle = 'ieldasafinalrTstingplaceforwhofoughtheregavetheirliZesthatthatn';
// strip out all non-letters
$regexp_to_strip_out = '/[^A-Za-z]/';
$haystack_letters = preg_replace($regexp_to_strip_out,'',$haystack);
list($start,$length) = shortest_edit_substring($needle,$haystack_letters);
list($real_start,$real_length) = map_substring($haystack_letters,$start,$length,$haystack,$regexp_to_strip_out);
printf("Found |%s| in |%s|, matching |%s|\n",substr($haystack,$real_start,$real_length),$haystack,$needle);
这也会进行纠错;它实际上比不这样做更容易。如果你想要比PHP更快的东西,那么在其他语言中实现最小编辑距离搜索非常简单。