代码之家  ›  专栏  ›  技术社区  ›  Node.JS

使用分治法在字符串中出现模式的频率

  •  1
  • Node.JS  · 技术社区  · 3 年前

    问题 :

    给定具有n个字符的字符串S和具有k个字符的模式P, 出现的一个自然问题是 P 出现在S中。例如,如果 S = CGATATATCCATAG 和 P = ATA ,则P在中出现三次 S ;也就是说, FREQ(S,P) = 3 。另一方面,当 P′ = AAT , FREQ(S,P′) = 0 因为在 S 等于 AAT 。

    a.给定S和P,设计一个蛮力算法(即最基本的算法),输出 FREQ(S,P) .你的算法运行时间是多少?你的答案应该是n和k。

    b.这一次,设计一个分而治之的算法,输出 频率(S,P) .你的算法运行时间是多少?你的答案应该是 n 和 k 。

    解决方案 :

    a) 我们使用移动窗口的方法来检查所有的可能性。

    def FREQ(S,k):
      count = 0
      for i in [0...length(S) - k]:
        if S.substring(i, length(k)) == k:
          count = count + 1
      
      return count
    

    此循环运行 length(S) - length(k) + 1 因此该算法运行的次数 O(|S| - |k| + 1) 时间。

    b) 我不确定如何使用分而治之,也不确定是否有什么能战胜线性时间复杂性。

    1 回复  |  直到 3 年前
        1
  •  1
  •   Abhinav Mathur    3 年前

    您可以修改您的模式匹配方法,使其使用分而治之。

    1. 分 S 分成两半 L 和 R 允许 l = FREQ(L,P) 和 r = FREQ(R,P) 。
    2. 您已经涵盖了发生在字符串任意一半中的所有事件。剩下的只有那些从左半场开始,但在右半场结束的球队。让这样的事件计数为 x 。
    3. 如果 k >= n , x = 0 否则,请使用滑动窗口技术查找索引之间的出现情况 [n/2 - k + 1, n/2 + k - 1] 。
    4. FREQ(S,P) = l + r + x 。

    递推关系可以给出为 T(n) = 2T(n/2) + 2k ,这样你就可以很容易地计算出D&C方法。