【问题标题】:Match symbol stream against dynamic patterns将符号流与动态模式匹配
【发布时间】:2017-02-23 03:45:59
【问题描述】:

您将如何解决以下问题:
给定一串可以随时添加的符号和模式,计算每个模式出现的频率。

示例
有一个连续的输入符号流让我们说 A B A C D E ... 用户可以随时注册一个新模式,例如(B A C)。如果模式在第二个时间步之前注册,则该模式应计算一次。

在重叠模式的情况下,仅应计算第一个模式,例如 (BAC)(ACD) 将仅导致 (BAC)被计算。

解决方法
简单的解决方案是每个模式只保留一个位置,当模式匹配时将其推进,并在匹配时重置所有位置。这将导致 O(n * m) 的运行时间 其中 n 是流的长度,m 是最长模式的长度(例如,在所有模式中具有长度为 m - 1 的相同前缀)。

另一种方法是构造一个有限自动机并使用模式可以具有组合前缀的事实。

但是有一些问题:

  • 如何构造图案之间的边缘? (例如 A B 中的 B D E

  • 如何在运行时添加模式。例如。假设流是 A B 并且目前只有模式 (A B C) 被注册。现在用户注册(B A C)。如果流以 A C D E 继续。该模式不应匹配,因为第一个符号在注册之前出现。

这个想法可以链接到Aho Corasick algorithm。然而,该算法确实匹配所有出现的模式,而不仅仅是第一个。它不允许在运行时添加模式。

【问题讨论】:

    标签: string algorithm match string-matching


    【解决方案1】:

    维护一个最初为空的 Aho-Corasick FSM 列表。每当注册一个新模式时,只为这个模式创建一个新的 FSM,将其附加到列表中,并检查列表末尾是否现在有 2 个单字符串 FSM:如果有,删除它们,构建一个新的两个字符串的 FSM,并用这个 FSM 代替原来的 2。现在检查是否有 2 个 2-string FSM,如果有,将它们组合成一个 4-string FSM。重复这个过程,将两个 k 字符串 FSM 组合成一个 (2k) 字符串 FSM,直到所有 FSM 都用于不同数量的字符串。 (请注意,相同数量的字符串的任意 2 个 FSM 必须位于列表中的相邻位置。)

    假设总共发生 n 次注册。由于上述“压缩”过程,列表将始终包含最多 log2(n)+1 个 FSM,因此使用这些 FSM 中的每一个进行搜索的总体“成本因素”输入流(与包含所有字符串的单个 FSM 相比)为 O(log n)。此外,特定字符串参与的 FSM 构建过程的数量上限为 log2(n)+1,因为它参与构建的每个新 FSM 必然是它参与构建的前一个 FSM 的两倍。因此,构建所有 FSM(相对于构建包含所有字符串的单个 FSM)的总体“成本因素”也是 O(log n)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-11
      • 2015-10-07
      • 2011-04-28
      • 2019-04-30
      • 2020-06-19
      • 2012-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多