快速文件系统路径与某些模式匹配(但没有wildchar)

时间:2017-08-14 08:17:53

标签: algorithm pattern-matching string-matching

假设一组(Unix)路径,例如

/usr
/lib
/var/log
/home/myname/somedir
....

给定路径/some/path,我想测试这个/some/path是否与上面路径中的任何一个匹配,并且,“匹配”,我的意思是

  1. /some/path正好是上述路径之一,或
  2. 它是上述路径之一的子路径。
  3. 我知道我可以通过/分割路径并逐个进行字符串匹配,但我想这么快,可能是通过使用一些散列技术或类似的东西,这样我可以转换这些字符串匹配一些整数匹配。

    有没有算法?或者,有没有证据证明它没有?

1 个答案:

答案 0 :(得分:1)

哈希表方法

由于路径通常不是很深,您可以负担得起存储所有可能的匹配子路径。

对于输入集中的每个路径,将其每个子路径添加到哈希表中。例如,这个集合:

/usr
/lib
/var/log
/home/myname/somedir

将生成此表:

hash0 -> /usr
hash1 -> /lib
hash2 -> /var
hash3 -> /var/log
hash4 -> /home
hash5 -> /home/myname
hash6 -> /home/myname/somedir

现在搜索查询归结为在此哈希表中找到完全匹配。只有在哈希冲突的情况下才需要进行字符串比较。

这种方法的一个主要缺点是,在一般情况下,它需要超线性的内存量(相对于输入集的大小)。

考虑600个字符长的路径:

[400characterlongprefix]/a/a/a/...[100 times].../a/a/a/

相应的表格总共包含50500个字符:

hash0   -> [400characterlongprefix]
hash1   -> [400characterlongprefix]/a
hash2   -> [400characterlongprefix]/a/a
...
hash100 -> [400characterlongprefix]/a/a/a/...[100 times].../a/a/a/

Trie方法

预计算步骤

  1. 将集合中的每个路径拆分为其组件。
  2. 为每个不同的组件分配一个索引,并将该对(组件,索引)添加到哈希表中。
  3. 对于每个路径,将其组件索引的序列添加到prefix tree
  4. 示例

    输入集:

    /usr
    /var/log
    /home/log/usr
    

    组件索引:

    usr  -> 0
    var  -> 1
    log  -> 2
    home -> 3
    

    前缀树:

    0            // usr
    1 -> 2       // var, log
    3 -> 2 -> 0  // home, log, usr
    

    搜索查询

    1. 拆分其组件的路径。
    2. 对于每个组件,在哈希表中查找其索引。
    3. 如果其中一个组件没有相应的索引,则报告不匹配。
    4. 在前缀树中搜索组件索引序列。