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

    问题定义:给定字符串string: abcdeabcea  以及匹配字符串parttern:  abce 问 parttern是否为string的子串,如果是请返回第一次出现索引的位置,否则返回-1

    以下是暴力匹配的代码:

    class Solution:
        def match(self, string,parttern):
            len1,len2 = len(string),len(parttern)
            i,j = 0,0
            while i<len1 and j<len2:
                if string[i]==string[j]:
                    i+=1
                    j+=1
                else:
                    i=i-j+1
                    j=0
            if j==len2:
                return i-j
            else:
                return -1

    KMP算法:

    暴力匹配算法是当string和parttern不匹配时,返回到string的下一个字符依次重新开始匹配。

    而KMP算法遇到string和parttern不匹配时,partttern向右移动。从而节约了时间。

    以下是KMP的代码:

     1 class Solution:
     2     def KMPmatch(self, string,parttern):
     3         len1,len2 = len(string),len(parttern)
     4         i,j = 0,0
     5         while i<len1 and j<len2:
     6             if j==-1 or string[i]==parttern[j]:
     7                 i+=1
     8                 j+=1
     9             else:
    10                 j = nextp[j]
    11         if j==len2:
    12             return i-j
    13         else:
    14             return -1

    KMP算法的描述:

    1: 当  j == -1 或者 匹配成功时 ,继续匹配

    2: 当 j!= -1 且不匹配时 i 不变, j = nextp[j]  (也就是 parttern向右移动了 j- next[p]个位置)

    下面介绍 nextp

    模式串parttern  为  abab

    模式串 a b a b
    最大前缀后缀公共元素长度 0 0 1 2

    ab的前缀为 a ,后缀为b   因此表格1,2为0

    aba的前缀为 a,ab 后缀为 ba,a  公共元素为a 因此表格为1 

    abab的前缀为  a , ab , aba , 后缀为 bab, ab,b   公共元素ab  因此表格为2

    nextp 即

     模式串

     a  b  a  b
     nexp  -1  0  0  1

    nextp数组就是将表格1中的最大前缀后缀公共元素长度的初值设为-1, 然后整体右移.

    nextp和最大长度表是等价的

    我们计算parttern向右移动的长度时.

    如果是用的最大长度表,  就是   j-当前不匹配元素的上一个元素在最大长度表中的值, 即 j-common[j-1]

    如果用的是nextp表,就是 j - next[j]

    构造数组nextp

    nextp通过递归的方式求得. 假设我们已经知道 nextp[j]的值为k, 那么nextp[j+1]的值为:

    如果  parttern[j] == parttern[k]  则 nextp[j+1] = next[j] + 1 = k+1

    如果 parttern[j] != parttern[k]  则 迭代 k = next[k]判断 parttern[k] ?= parttern[j]  直到相等或者 next[k]=-1为止.

    以下为整个代码部分.python

     1 class Solution:
     2     def getnext(self,parttern):
     3         nextp = [0]*len(parttern)
     4         nextp[0] = -1
     5         k,j = -1,0
     6         while j<len(parttern)-1:
     7             if k==-1 or parttern[j]==parttern[k]:
     8                 j+=1
     9                 k+=1
    10                 nextp[j] = k
    11             else:
    12                 k = nextp[k]
    13         return nextp
    14 
    15     def KMPmatch(self, string,parttern):
    16         len1,len2 = len(string),len(parttern)
    17         nextp = self.getnext(parttern)
    18         i,j = 0,0
    19         while i<len1 and j<len2:
    20             if j==-1 or string[i]==parttern[j]:
    21                 i+=1
    22                 j+=1
    23             else:
    24                 j = nextp[j]
    25         if j==len2:
    26             return i-j
    27         else:
    28             return -1
  • 相关阅读:
    笔记35 跨重定向请求传递数
    判断邮箱的正则表达式
    按钮
    async await 的用法
    笔记34 Spring MVC的高级技术——处理multipart形式的数据
    Convert Sorted Array to Binary Search Tree
    Binary Tree Zigzag Level Order Traversal
    Unique Binary Search Trees,Unique Binary Search Trees II
    Validate Binary Search Tree
    Populating Next Right Pointers in Each Node,Populating Next Right Pointers in Each Node II
  • 原文地址:https://www.cnblogs.com/bianque/p/13548739.html
Copyright © 2011-2022 走看看