zoukankan      html  css  js  c++  java
  • KMP 算法学习

    KMP算法是用来做字符串匹配的。关于字符串匹配,最简单最容易想到的方法是暴利查找,使用双重for循环处理。

    该方法的时间复杂度为O((n-m+1)*m) (n为目标串T长度,m为模式串P长度, 从T中寻找是否有P串存在)。

    暴利的问题是在匹配中没有利用之前比较的信息。而这些信息可能是非常有用的。所以是可以进行优化以降低时间复杂度。

    而KMP算法就是一个利用模式串来构造计算不匹配时计算模式串和目标串比较的位置,避免回溯。

    KMP的思想为利用字符串的后缀串信息。

    对于某个字符串y,如果有字符串w,满足字符串x = wy, 那么称y为x的后缀字符串。而其中最长的y为最长后缀字符串

    我们对P字符串计算其后缀字符串信息,

    KMP算法的伪代码如下:(注意下面的伪代码从1开始算起,而不是0)

    KMP_MATCHER(T,P):

         n = length(T)

         m = length(P)

         ComputeNextFunction(P)

         k = 0

         for q = 1 to n:

             while (k > 0 && P[k +1] != T[i])

                  k = Next[k];

              if [ P[k+1] == T[i] ]

                   ++k

              if [ k == m ]

                 print “Matched”

                 k = Next[k] 

    求Next数组的伪代码如下:

    ComputeNextFunction(P):

        m = length(P)

        k = 0

        Next[1] = 0

        for q =2 to m

           while k > 0 && P[k+1] != P[q]

                k = Next[k] 

            if P[k+1] == P[q] :

               ++k

            Next[q] = k

        return Next

    Next 数组求的就是最大的k值是的Pk是Pq的后缀字符串。

    这样当到P串的第q个字符串和目标串不匹配的时候,从1到K的字符串和P[q-k -1] 到q个字符串是相等的(后缀字符串)。所以是不需要再进行比较的。可以直接跳过。

  • 相关阅读:
    UVa 1451 Average (斜率优化)
    POJ 1160 Post Office (四边形不等式优化DP)
    HDU 3507 Print Article (斜率DP)
    LightOJ 1427 Substring Frequency (II) (AC自动机)
    UVa 10245 The Closest Pair Problem (分治)
    POJ 1741 Tree (树分治)
    HDU 3487 Play with Chain (Splay)
    POJ 2828 Buy Tickets (线段树)
    HDU 3723 Delta Wave (高精度+calelan数)
    UVa 1625 Color Length (DP)
  • 原文地址:https://www.cnblogs.com/lovemdx/p/3280769.html
Copyright © 2011-2022 走看看