【问题标题】:fast filesystem path matching with some pattern (but no wildchar)与某些模式匹配的快速文件系统路径(但没有通配符)
【发布时间】:2018-01-22 00:55:20
【问题描述】:

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

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

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

  1. /some/path 正是上述路径之一,或者
  2. 它是上述路径之一的子路径。

我知道我可以通过/ 分割路径并逐个进行字符串匹配,但我想非常快地做到这一点,可能通过使用一些散列技术或类似的东西,以便我可以将这些字符串匹配转换为一些整数匹配。

有任何算法吗?或者,有什么证据证明它没有?

【问题讨论】:

    标签: algorithm pattern-matching string-matching


    【解决方案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/
    

    尝试方法

    预计算步骤

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

    示例

    输入集:

    /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. 在前缀树中搜索组件索引序列。

    【讨论】:

      猜你喜欢
      • 2023-04-09
      • 1970-01-01
      • 2020-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-21
      • 1970-01-01
      相关资源
      最近更新 更多