比O(n)glob匹配器好吗?

时间:2011-03-25 14:58:52

标签: c++ algorithm glob

问题:鉴于globs的列表,我需要从列表中找到(并返回)给定字符串匹配的glob或最终确定没有匹配的。设置时间,性能必须优于所有整体的线性搜索:

foreach glob in list:
  if glob.matches(string):
    return glob
return None

问题:是否有可用的库(C ++首选)?


编辑:经过一番思考,我想我可以说这可以做到。鉴于globs具有不同语法的正则表达式,使用glob语法的lex的运行时版本将符合要求。

鉴于问题可以简单地减少到已知问题,我仍然只对实施的解决方案感兴趣。

5 个答案:

答案 0 :(得分:7)

将您的globs转换为正则表达式(一系列简单的字符串操作可以实现此目的 - *变为.*等)。使用|将它们组合成单个正则表达式,并将结果分配给每个glob的不同捕获组,以便在匹配时确定匹配的glob。依靠你最喜欢的正则表达式库将正则表达式编译成一个DFA,这个DFA希望比组成部分的线性遍历更加优化,这是可能的 - 但是,在最一般的情况下,它不会更快。 / p>

答案 1 :(得分:5)

Globs是正则表达式的子集(关于表达能力,而不是确切的语法)。因此,Globs可以转换为确定性有限自动机(DFA),并且可以将它们组合在一起形成单个DFA,以识别单个DFA的并集。 DFA具有O(n)的复杂度,n是字符串的长度。自动机构造的Globs数量仅影响设置时间(即创建自动机),而不影响运行时间。

答案 2 :(得分:0)

我不认为有可能比整数的线性时间更好。为了证明字符串与任何一个字符串不匹配,你必须检查每个字符串是否匹配,否则你永远不会知道你跳过的字符串是否匹配。

编辑:在一般情况下,使用globs是不可能的。正如评论中所指出的那样,可以组合一些globs组合(首先猜测trie可能有用,其中每个节点指示下一个匹配的字母和你仍然需要检查的globs),导致较少量的工作搜索。

在一般情况下,也可以将一组globs转换为相应的正则表达式。

这种匹配的性能真的是一个你需要改进它的问题吗?您是否考虑过更为基础的算法重写可能更好?

答案 3 :(得分:0)

可能只是在某些特定情况下。如果你能以某种方式预测某些globs与你的字符串不匹配。

答案 4 :(得分:0)

我会查看您的应用是否适合shift-reduce parser bison。他们使用查找表,这是设置或更改和使用更多内存的痛苦,但速度非常快。从技术上讲,物理上不可能比O(n)最坏情况更好,但取决于你的整数,你的字符串和你的标记器,使用这样的技术可以使你的平均值< / em>情况好多了,因为它消除了匹配的模式,而不必每次都检查每个模式。