用字符串搜索字符串。通配符

时间:2011-02-02 00:33:57

标签: algorithm string search complexity-theory big-o

我有一个包含如此多字符串的数组,并希望在其上搜索模式。 这种模式可以有一些“。”匹配(每个)1个字符(任意)的通配符。

例如:

myset = {"bar", "foo", "cya", "test"}

find(myset, "f.o") -> returns true (matches with "foo") 
find(myset, "foo.") -> returns false 
find(myset, ".e.t") -> returns true (matches with "test")
find(myset, "cya") -> returns true (matches with "cya")

我试图找到一种快速实现此算法的方法,因为myset实际上是一个非常大的数组,但我的想法都没有令人满意的复杂性(例如O(size_of(myset) * lenght(pattern))

修改

myset是一个巨大的数组,其中的文字并不大。 我可以做一个缓慢的预处理。但是我会有很多find()次查询,所以find()我希望find()尽可能快。{{1}}

5 个答案:

答案 0 :(得分:2)

您可以在集合中构建所有可能单词的语料库的后缀树(see this link) 使用这种数据结构,您的复杂性将包括构建树的一次性O(n)成本,其中n是所有单词长度的总和。

构建树后,查找字符串匹配是否只需要O(n),其中n是字符串的长度。

答案 1 :(得分:1)

如果设置是固定的,您可以预先计算位于c的字符p的频率(对于您认为值得的p个值),然后搜索数组一次,为每个元素测试一个顺序中特定位置的字符,以便您最有可能提前退出。

答案 2 :(得分:1)

首先,将语料库划分为每个单词长度的集合。然后,您的查找算法可以搜索适当的集合,因为find()的输入始终要求匹配具有特定长度,并且算法可以设计为与所有相同长度的单词一起使用。

接下来(对于每个集合),从字符x位置的散列到匹配单词列表创建散列映射。有大量的哈希冲突是完全可以的。您可以使用增量和行程编码来减小匹配单词列表的大小。

要搜索,请为查找输入长度选择适当的哈希映射,并为每个非.字符计算该字符x位置的哈希值,并将AND一起计算单词列表,得到一个大大减少的名单。

通过更小的列表进行暴力搜索。

答案 3 :(得分:0)

如果您确定集合中单词的长度不大。您可以创建一个包含以下内容的表:

具有第一个字符'a'的单词列表,具有第一个字符'b'的单词列表,..

具有第二个字符'a'的单词列表,具有第二个字符'b'的单词列表,..

等等。

当你搜索这个词时。您可以查找与搜索字符串的第一个字符相同的第一个字符的单词列表。使用此精炼列表,查找具有与搜索字符串的第二个字符相同的第二个字符的单词,依此类推。你可以忽略'。'无论何时遇到它们。

据我所知,建造桌子可能会占用大量空间,但所花费的时间会大幅减少。

例如,如果您有myset = {“bar”,“foo”,“cya”,“test”}并且您正在搜索“f.o”

当您检查以f开头的单词列表时,您将消除该组的其余部分。只是一个想法..希望它有所帮助。

答案 4 :(得分:0)

我有同样的问题,我对在互联网上找到的大多数想法/解决方案并不完全满意。我认为这样做的“正确”方法是使用Directed Acyclic Word Graph。我没有那么做,但我在Trie添加了一些额外的逻辑以获得类似的效果。

请参阅我的isWord()实施,类似于您想要的find()界面。它通过递归Trie,在通配符上分支,然后将结果收集回公共集合来工作。 (见findNodes()。)

getMatchingWords()在精神上是相似的,除了它返回匹配单词的集合,而不仅仅是关于查询是否与任何内容匹配的布尔值。