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

  • 相关阅读:
    屏幕的真实分辨率大小
    CCConfiguration::sharedConfiguration()->loadConfigFile cocos2d-x 中文乱码问题及国际化解决方案
    git 放弃提交到提交之前
    cocos2d-x 输出debug信息
    Ubuntu设置环境变量
    有时候需要统计手机的型号和版本号,利用程序可以获取到相应的手机信息.
    读取 android sys/下的信息
    android 读取 raw 中的文件。
    C/C++中结构体(struct)
    异步图片下载引擎(升级版——ExecutorService+handler)
  • 原文地址:https://www.cnblogs.com/xxswkl/p/12688287.html
Copyright © 2011-2022 走看看