我有一大堆单词(大约10,000个),我需要查找这些单词是否出现在给定的文本块中。
是否存在比对文本块中的每个单词进行简单文本搜索更快的算法?
答案 0 :(得分:17)
将10,000个单词输入哈希表,然后检查文本块中的每个单词是否有哈希值。
虽然我不知道更快,但只是另一种方法(取决于你要搜索的单词数量)。
简单的perl例子:
my $word_block = "the guy went afk after being popped by a brownrabbit";
my %hash = ();
my @words = split /\s/, $word_block;
while(<DATA>) { chomp; $hash{$_} = 1; }
foreach $word (@words)
{
print "found word: $word\n" if exists $hash{$word};
}
__DATA__
afk
lol
brownrabbit
popped
garbage
trash
sitdown
答案 1 :(得分:11)
尝试Aho-Corasick算法: http://en.wikipedia.org/wiki/Aho-Corasick_algorithm
答案 2 :(得分:5)
构建trie个单词,然后使用它来查找文本中的单词。
答案 3 :(得分:4)
答案很大程度上取决于实际要求。
假设相对于单词列表相对较小的文本块并且只处理每个文本块一次,我建议将单词列表中的单词放入哈希表中。然后,您可以对文本块中的每个单词执行哈希查找,并查明单词列表是否包含单词。
如果你必须多次处理文本块,我建议反转文本块。反转文本块意味着为包含包含特定单词的所有文本块的每个单词创建一个列表。
在其他情况下,为每个文本块生成一个位向量可能会有所帮助,每个字一位指示该字是否包含在文本块中。
答案 4 :(得分:1)
你可以建立一个用作状态机的图形,当你处理输入词的第i个字符时 - Ci - 你试着通过检查你的前一个节点是否与Ci-1相连来转到图的第i层。 ,有一个与Ci相关联的子节点
例如:如果你的语料库中有以下单词
(“艺术”,“是”,“是”,“蜜蜂”)
您的图表中将包含以下节点
n11 ='a'
n21 ='r'
n11.sons =(n21)
n31 ='e'
n32 ='t'
n21.sons =(n31,n32)
n41 ='art'(这里我们的图中有一个叶子,所有上层节点的构建单词与该节点相关联)
n31.sons =(n41)
n42 ='是'(这里我们还有一个词)
n32.sons =(n42)
n12 ='b'
n22 ='e'
n12.sons =(n22)
n33 ='e'
n34 ='be'(word)
n22.sons =(n33,n34)
n43 ='bee'(字)
n33.sons =(n43)
在你的过程中,如果你在处理输入单词的最后一个字符时经过一个叶子,并且只有在这种情况下,这意味着你的输入在你的语料库中。
这个方法实现起来比单个Dictionary或Hashtable更复杂,但在内存使用方面会更加优化
答案 5 :(得分:0)
Boyer-Moore string algorithm应该有效。根据文本块中的大小/#或单词,您可能希望将其用作搜索单词列表的键(列表中是否有更多单词,然后在块中)。此外 - 您可能希望从两个列表中删除任何重复项。