IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> OJ:字符串KMP算法 Python实现 -> 正文阅读

[数据结构与算法]OJ:字符串KMP算法 Python实现

KMP算法是一种字符串匹配算法,可以在 O(n+m) 的时间复杂度内实现两个字符串的匹配。

字符串匹配:“字符串 P 是否为字符串 S 的子串?如果是,它出现在 S 的哪些位置?” 其中 S 称为主串;P 称为模式串。

教程:https://www.zhihu.com/question/21923021/answer/1032665486

输入:主串s,模式串p

输出:匹配位置列表

过程:

  1. 计算next数组。

    next数组是对于模式串而言的,定义为:next[i] 表示模式串p[:i+1]中,长度为k的前缀恰等于后缀的最大的k,其中k必须小于自身长度i.

    起始条件:next[0] = 0

    计算i位置的结果时,我们首先考虑利用ptr=i-1位置的结果。在知道next[ptr]=k时,说明p[0:k] == p[i-k:i],如果p[k] == p[i],则next[i] = next[ptr]+1.

    如果不相等,需要重新找尽量大的j<k,满足p[0:j] == p[i-j:i],再试图扩展。

    考虑到p[i-j:i] == p[k-j:k],那么j=next[k-1]是符合要求的。

    重新赋值ptr = k-1, k = next[ptr],以此法继续迭代下去即可。因为forall i, next[i] <= i,所以每次迭代ptr必然变小。ptr<0时迭代结束,next[i]的结果确定为0.

    # calculate next
    next = [0]
    for i in range(1, len(p)):
        ptr = i-1
        while ptr >= 0: 
            if p[next[ptr]] == p[i]: 
                next.append(next[ptr] + 1)
                break
            else:
                ptr = next[ptr] - 1
        else:
            next.append(0)
    
  2. 根据next数组计算匹配位置。

    起始条件:主串和模式串指针都在开头。i, j = 0, 0

    匹配过程:当成功匹配s[i] == p[j]时,正常移动指针。

    当匹配失败时,如果j > 0,我们尽量利用这段历史匹配记录。记next[j-1]=k (k<j),那么根据next数组的性质和历史匹配记录,我们可以知道:s[i-j:i] == p[0:j], p[0:k] == p[j-k:j]

    所以s[i-k:i] == p[0:k],可以把指针j移动到k继续匹配。这样就最大化地利用了这段历史匹配记录。

    类似地,匹配成功时也要重新开始一次新的匹配。此时也可以用同样的方法,不浪费之前的匹配记录。

    # KMP
    i, j = 0, 0
    ret = []
    while i < len(s):
        if s[i] == p[j]: 
            i, j = i+1, j+1
        elif j > 0:
            j = next[j-1]
        else:
            i += 1
        if j == len(p):
            ret.append(i - len(p))
            j = next[j-1]
    

    ret数组即为所求。

KMP的变体主要是考虑到,KMP算法可以求出对于每一个位置,s的后缀与p的前缀匹配的最大长度,即对于s的每一个位置i,满足s[i-j:i] == p[0:j]的最大的j. 有一些任务可以基于这个性质解决。

例题:LeetCode 214 Shortest Palindrome

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 20:49:54  更:2022-03-22 20:51:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 11:26:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码