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

    KMP算法的关键和难点是next数组的构建,next数组是由模式串生成的状态转移数组,next[i]表示当模式串needle[i]与主串的的不匹配时,需要跳到needle[next[i]]进行比较,

    class Solution:
        def strStr(self, haystack: str, needle: str) -> int:
            if needle == "":
                return 0
            # 生成next数组,用于记录状态的转移
            i, k, m = 0, -1, len(needle)
            # 初始值
            pnext = [-1] * m
            # i指针从0开始到匹配串的末尾
    
            # next[i]表示当needle[i]与haystack[h]不匹配时,这时需要状态转移,也就是说haystack[h]该与哪个needle[i]比较
            # next[i]给出了答案,即haystack[h]与needle[next[i]]比较,即从i状态转移到next[i]状态,而k就等于next[i],
            # 也就是说k表示要转移到的状态,如果所有的状态是从0到len(needle)-1,则忽略了当模式串的第0个字符与主串不匹配
            # 时,需要移动主串的情况(这时再移动模式串无效),所以将k初始化为-1,
            while i < m-1:
                # 如果k等于-1,则表示needle[i]前面不存在最长公共前后缀,此时需要直接跳到needle的开头进行比较,所以赋值为k+1为0
                # 如果needle[i]等于needle[k],needle[k]表示needle[i](不含needle[i])的最长公共前后缀,k是其索引,
                # k+1是下一个要比较的索引,所以要加一,
                #
                if k == -1 or needle[i] == needle[k]:
                    i += 1
                    k += 1
                    pnext[i] = k
                    # 这里结束时,needle[i]和needle[k]还没有比较,但是needle[i-1](包含needle[i-1])的最长公共前后缀已经知道了,
                    # 是needle[k-1],所以下一步首先要比较needle[i]和needle[k]是否相等,如果相等,则最长公共前后缀加1,否则改变k,
                    # 如果下一步比较的时候,k不等于-1,并且needle[i]不等于needle[k],则此时必须找到以needle结尾的最长公共前后缀,
                    # pnext[k]表示needle[k]的最长公共前后缀的长度,当pnext[k]作为索引时,表示最长公共前后缀的下一个元素,而这里我们
                    # 正是要比较下一个元素与needle[i]是否相等,
                else:
                    k = pnext[k]
            print(pnext)
            # matching
            h, j = 0, 0
            n = len(haystack)
            # 两个指针必须小于字符串长度
            # 结束只有两种情况,一种是主串都遍历完了,没有匹配的,
            # 另一种是模式串遍历完了,有匹配的,
            while h < m and j < n:
                # 如果h等于-1表示对模式串needle从头开始比较,因为h+1等于0,而主串haystack也要后移一位
                # 如果needle[h] == haystack[j]表示当前匹配相等,则指针都向后移一位,比较下一个,
                if h == -1 or needle[h] == haystack[j]:
                    h, j = h + 1, j + 1
                # 如果不相等,即当前模式串和主串不相等时,则对模式串进行状态转移,确定和主串比较的模式串中的下一个字符
                else:
                    h = pnext[h]
            # 比较结束后,如果匹配串的值指向了末尾再加1,则说明匹配成功,返回
            if h == m:
                return j - h
            return -1
    # 作者:jia - zhi - tong - 1
    # 链接:https: // leetcode - cn.com / problems / implement - strstr / solution / kmpshi - xian - by - jia - zhi - tong - 1 /
    # 来源:力扣(LeetCode)
    # 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    if  __name__ == '__main__':
        solution = Solution()
        # result = solution.strStr(haystack='BBCABCDABABCDABCDABDE',needle='ABCDABD')
        # result = solution.strStr(haystack='BBCABCDABABCDABCDABDE',needle='ABCDABD')
        # result = solution.strStr(haystack='BBCABCDABABCDABCDABDE',needle='ABCABCFE')
        result = solution.strStr(haystack='BBCABCDABABCDABCDABDE',needle='ABABAB')
        print(result)
    View Code

    ttt

    参考:https://blog.csdn.net/czywangye/article/details/88852702?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2

    http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

  • 相关阅读:
    Theano入门笔记1:Theano中的Graph Structure
    [译博文]CUDA是什么
    一天一经典Efficient Estimation of Word Representations in Vector Space
    Generating a Random Sample from discrete probability distribution
    关于representation的理解
    git代码管理——克隆项目到本地仓库及上传本地项目到仓库
    yum管理——linux字符界面安装图形化及两种界面的切换(3)
    yum管理——yum常用配置(2)
    yum管理——搭建iso镜像私有yum源仓库(1)
    apche编译安装
  • 原文地址:https://www.cnblogs.com/xxswkl/p/12688287.html
Copyright © 2011-2022 走看看