KMP算法详解

2023-10-27

一,什么是KMP算法

KMP主要应用在字符串匹配上。

KMP的主要思想是当出现字符串不匹配时,通过已知一部分之前已经匹配的内容,避免从头再去做匹配

所以KMP算法的重点就是如何记录已经匹配的信息,也就是next 数组的实现

二,什么是next数组

next数组也就是前缀表。

前缀表有什么用处呢,它是在字符串不匹配时,用来确定回退位置的。

那我们来举个例子:

文本串 :ababcabfababcabd                          模式串: ababcabd

 

首先要知道前缀表的任务是当前位置匹配失败,找到之前已经匹配上的位置,再重新匹配,此也意味着在某个字符失配时,前缀表会告诉你下一步匹配中,模式串应该跳到哪个位置。

前缀表的定义是:记录当前位置之前的字符串中,最长相同前后缀。

三,最长相同前后缀

前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串

后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串

所以如模式串ababcabd

字符串为a 的最长相等前后缀为0,为ab的最长相等前后缀为0,为aba的最长相等前后缀为1

为abab的最长相等前后缀为2  为ababc的最长相等前后缀为0,为ababca的最长相等前后缀为1

为ababcab的最长相等前后缀为2  为ababcabd的最长相等前后缀为0;

所以next数组就为 0 0 1 2 0 1 2 0

那如何使用next数组呢 

四, 构建next数组

 1,初始化

定义两个指针i和j,j指向前缀起始位置,i指向后缀起始位置。

int j=0;
next[0]=j;

完整构建代码

void getNext(string s){
    int j = 0;
    next[0] = j;
    for(int i = 1; i < s.size(); i++) { // j要保证大于0,因为下面有取j-1作为数组下标的操作
        while (j > 0 && s[i] != s[j]) { // 前后缀不相同了
            j = next[j-1]; // 向前回退
        }
        if (s[i] == s[j]) { // 找到相同的前后缀
            j++;
        }
        next[i] = j; // 将j(前缀的长度)赋给next[i]
    }
}

五,完整代码实现

#include<bits/stdc++.h>
#define MAX 10000
using namespace std;
int next[MAX];
void creat(string s)
{
	int j=0;
	next[0]=j;
	for(int i=1;i<s.size();i++)
	{
		while(j>0&&s[i]!=s[j])
		{
			j=next[j-1];
		}
		if(s[i]==s[j])
		{
			j++;
		}
		next[i]=j;
	}
}
int solve(string p,string s)
{
	int j=0;
	for(int i=0;i<p.size();i++)
	{
		while(j>0&&p[i]!=s[j])   // 不匹配
		{
			j=next[j-1];    // j 寻找之前匹配的位置
		}
		if(p[i]==s[j])      // 匹配,j和i同时向后移动
		{
			j++;
		}
		if(j==s.size()-1)   // 文本串s里出现了模式串t
		{
			return (i-s.size()+1);
		}
	}
}
int main()
{
	string p,s; //p为文本串,s为模式串 
	cin>>p>>s;
	creat(s);
	cout<<solve(p,s)<<endl;   
	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

KMP算法详解 的相关文章

随机推荐

  • pytest多进程/多线程执行测试用例

    前言 实际项目中的用例数量会非常多 几百上千 如果采用单进程串行执行的话会非常耗费时间 假设每条用例耗时2s 1000条就需要2000s approx 33min 还要加上用例加载 测试前 后置套件等耗时 导致测试执行效率会相对低 想象一下
  • Ubuntu 18.04安装QtCreator+配置qt环境+qtchooser

    文章目录 前言 安装 配置 安装QtCreator 配置Qt环境变量 qtchooser 什么是qtchooser 方法1 方法2 前言 写这个博客的时候 我用了一段时间的QtCreator 感觉良好 足以说是一个很好的C 的IDE了 但是
  • 51单片机中断知识整理

    AT89C51单片机学习整理 一 一 中断结构图 TCON SCON IE IP均为与中断有关的寄存器 IE0 为外部中断INT0的中断标志位 IE1 为外部中断INT1的中断标志位 TF0 为定时器T0的中断标志位 TF1 为定时器T1的
  • window.open()的奇妙冒险

    前言 一个简单的优化需求 竟然引发了window open 的奇妙化学反应 背景 项目X的A页面需要点击一个区域后 跳转到对应的页面B 这个页面需要新开窗口来展示 B页面成功打开后再起接口还在loading的时候关闭 会造成当前浏览器中所有
  • TinyMCE自定义表情包

    记录一次接手别人代码的经历 TinyMCE自定义表情包 那个xxx没做过表情功能 你在xxx项目做过 这个功能你来完成吧 一句简短的话语 开启了改造表情之路 简单了解一下项目 使用的是vue结合TinyMCE富文本 开始造吧 一 效果图 整
  • 164道网络安全工程师面试题(附答案)

    最近有不少小伙伴跑来咨询 想找网络安全工作 应该要怎么进行技术面试准备 工作不到 2 年 想跳槽看下机会 有没有相关的面试题呢 为了更好地帮助大家高薪就业 整理了上百道网络安全工程师面试题 希望它们能够帮助大家在面试中 少走一些弯路 更快拿
  • 金融行业数据模型

    一 Teradata FS LDM Teradata 公司基于金融业务发布的FS LDM Financial Servies Logical Data Model 十大主题 当事人 产品 协议 事件 资产 财务 机构 地域 营销 渠道 1
  • Matlab信号处理,小波降噪

    最近在学小波降噪 分享一些代码帮助大家理解 本文使用matlab进行小波降噪 采用固定阈值方式 对一维噪声数据进行降噪处理 在matlab信号处理书中的一些代码分享一下 信噪比snr为信号与噪声信号的功率比的对数 信号功率计算公式 wden
  • LeetCode题目笔记——448. 找到所有数组中消失的数字

    文章目录 题目描述 题目链接 题目难度 简单 方法一 使用额外空间 字典 代码 Python 代码 C 方法二 进阶 原地修改 代码 C 代码 C 总结 题目描述 这好像是一到经典的面试题 给你一个含 n 个整数的数组 nums 其中 nu
  • matlab实现混沌系统最大李雅普诺夫指数

    李雅普诺夫指数 Lyapunov 是一个较为典型的判断一个系统是否具有混沌特性以及混沌的程度分析方法 李指数 在相空间中初始时无限接近的两个轨道 随着时间的不断推移按指数收敛或发散的平均变化率 它可以定量描述混沌系统在局部范围里系统轨道间的
  • Electron 自定义顶部菜单和上下文菜单

    自定义顶部菜单 文章目录 自定义顶部菜单 1 主进程 2 渲染进程定义顶部菜单 3 实现效果 4 渲染进程定义上下文菜单 5 实现效果 1 主进程 main js 代码如下 示例 main js const electron require
  • 实时分割算法常用思想

    目录 1 替换主网络 2 减少通道数 3 减少卷积层 4 将卷积层替换为组卷积层或其他能减少计算量的卷积操作 5 增加前期数据处理 6 减少复杂的融合方式 7 避免使用全连接 1 替换主网络 将参数量较大的网络替换为参数量小的网络 如 Re
  • qt中new与delete的使用

    qt中有时候使用new后并没有使用delete 原因是 Qt 自动回收是靠父子关系 父亲销毁了 他的孩子也销毁 include mainwindow h include
  • 【Transformer系列(2)】注意力机制、自注意力机制、多头注意力机制、通道注意力机制、空间注意力机制超详细讲解

    前言 注意力机制一直是一个比较热的话题 其实在很早之前就提出了 我们在学习图像分类时在SENet就见到过 直通车 经典神经网络论文超详细解读 七 SENet 注意力机制 学习笔记 翻译 精读 代码复现 自从谷歌发表了 Attention I
  • css 实现汉堡包式菜单

    title css 实现汉堡包式菜单 tags css time 2018 12 01 CSS3 实现汉堡包式菜单 html div class container div
  • 网络安全的规划

    防火墙被应用于内部网与外部网的连接之间 通过2 6 块 100M 快速以太网 卡直接连在 交换机上 使用虚拟网 VLAN 技术 来自 INTERNET 对内部网 12 的访问首先要经过防火墙 防火墙对进出内部网的数据内容进行各个层次的安全
  • C++指向类成员(数据、函数)的指针

    指向 类 的成员的指针包含两种 指向 类 的数据成员的指针 指向 类 的成员函数的指针 注意 指向的是 类的成员 和类发生关系 指向非静态公有数据成员的指针 在定义时必须和类相关联 在使用时必须和对象相关联 1 指向类的数据成员的指针 1
  • BestCoder Round #36 HDU(5198 - 5201)

    人生第一次ak了bc 当然要写个题解装逼一下 其实是题水 Hdu 5198 Strang Class 水题 不过wa了两发 include
  • 【2023版】Nmap的概述、安装并进行网络扫描实战

    Nmap概述 Nmap Network Mapper 网络映射器 是一个网络连接端扫描软件 用来扫描网上电脑开放的网络连接端 确定哪些服务运行在哪些连接端 并且推断计算机运行哪个操作系统 这是亦称 fingerprinting 它是网络管理
  • KMP算法详解

    一 什么是KMP算法 KMP主要应用在字符串匹配上 KMP的主要思想是当出现字符串不匹配时 通过已知一部分之前已经匹配的内容 避免从头再去做匹配 所以KMP算法的重点就是如何记录已经匹配的信息 也就是next 数组的实现 二 什么是next