当前位置: 首页 > article >正文

kmp算法讲解

当我们在进行两个字符串判断时,我们最坏的打算的时间复杂度是n*m

这将会导致我们的时间是与给定的字符串挂钩的

那么,如何缩短判定时间呢


KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)

next数组解释

什么是next数组,可以想象一下,当你在匹配时,以 i 为起点,匹配了 j-1个字符,但是第j个字符的时候,匹配的字符不相同,那该怎么办,这个匹配的字符串假设还有利用价值,也就是说,以i为起点,j为长度的字符串在后缀有存在于匹配字符串的子串时,是还有剩余价值的,这个时候,可以转到最大的前缀,这时候,当前的k应该为匹配的开头

如何实现nx数组

因为我们是匹配字符串,所以要在需要匹配的字符串种做操作,那么如何去做呢

因为我们现在在匹配过程中,如果出现当前位置字符不同的时候,只需要看当前位置我们能匹配长度为 l 的最大的前缀后缀的长度即可

//以下代码基于字符串从0开始c++版本 s2代表匹配字符串
for(int i=1,j=0;s2[i];i++)
{
    //初始的时候,待匹配字符的下标应该是1,因为我匹配下标一直是从0开始(最大前缀)
    while(j&&s2[i]!=s2[j])j=nx[j-1];//j代表当前匹配到的字符,如果说现在你的两个位置字符不能匹配,那么我就需要向之前位置的转移
    if(s2[i]==s2[j])j++;//如果当前我能进行匹配,长度加一
    nx[i]=j;//最后,顶下我当前位置的长度
}

匹配过程

//以下代码基于字符串从0开始c++版本 s1代表待匹配字符串
for(int i=0,j=0;s1[i];i++)
    {
    //i代表s1现在为止的下标
    //现在要对于你两个位置进行匹配,我待匹配字符串一定是不洞的,看我匹配字符串能否匹配
        while(s1[i]!=s2[j]&&j)j=nx[j-1];
        if(s1[i]==s2[j])j++;
        //如果可以就break,这里看题目意思
        if(j==s2.size())break;
    }

总体code

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+7;
int nx[N];
int main()
{
    string s1,s2;
    cin>>s1>>s2;
    for(int i=1,j=0;s2[i];i++)
    {
        while(j&&s2[i]!=s2[j])j=nx[j-1];
        if(s2[i]==s2[j])j++;
        nx[i]=j;
    }
    int ans=0;
    for(int i=0,j=0;s1[i];i++)
    {
        while(s1[i]!=s2[j]&&j)j=nx[j-1];
        if(s1[i]==s2[j])j++;
        if(j==s2.size())
        {
            cout<<"yes";
            return 0;
        }
    }
    cout<<"no";
    return 0;
}

2024.2.4

训练!!!

训练!!!训练!!!训练!!!

训练!!!训练!!!训练!!!训练!!!训练!!!


http://www.kler.cn/a/228344.html

相关文章:

  • 动态内存管理
  • USART_串口通讯轮询案例(HAL库实现)
  • 数据结构:二叉树
  • Spring Boot整合Thymeleaf、JDBC Template与MyBatis配置详解
  • 【深度学习】嘿马深度学习笔记第11篇:卷积神经网络,学习目标【附代码文档】
  • c语言的分支与循环
  • 华清远见嵌入式学习——春节作业——2.5日
  • [ubuntu]add-apt-repository 添加以及移除
  • 假期作业 2.2
  • 哪种安全数据交换系统,可以满足信创环境要求?
  • 视频业务像素、带宽、存储空间计算
  • OpenCV学习记录——平滑处理
  • 【ARM Trace32(劳特巴赫) 使用介绍 3.1 -- 不 attach core 直接访问 memory】
  • 【linux】校招中的“熟悉linux操作系统”一般是指达到什么程度?
  • ubuntu 安装 ffmpeg 6.0
  • 设计模式概述
  • 如何结合ChatGPT生成个人魔法咒语词库
  • 【UE 材质】球形遮罩材质
  • 【力扣经典面试题】189. 轮转数组
  • C++新特性 扩展和聚合类型
  • 网易腾讯面试题精选----50 个 Git 面试问题
  • 笔记本电脑的WIFI模块,突然不显示了,网络也连接不上
  • 计算机软件能力认证考试CCF-202312-1 仓库规划
  • 《剑指 Offer》专项突破版 - 面试题 30 和 31:详解如何设计哈希表以及利用哈希表设计更加高级、复杂的数据结构
  • 远程桌面时连接不上远程计算机是什么问题
  • YOLOv8改进 | 检测头篇 | 重参数化检测头RepHead解决困难样本检测(全网独家首发)