C++数据结构7:KMP处理字符串

数据结构与算法专题之串——字符串及KMP算法 本章是线性表的最后一部分——串。其实串就是我们日常所说的字符串,它是一系列结点组成的一个线性表,每一个结点存储一个字符。我们知道C语言里并没有字符串这种数据类型,而是利用字符数组加以特殊处理(末尾加'\0')来表示一个字符串,事实上数据结构里的串就是一个存储了字符的链表,并且封装实现了各种字符串的常用操作。   串的概念和定义其实没什么好说的,本章的主要内容是KMP算法,也就是字符串模式匹配算法 阅读详情

1、KMP概念

KMP(Knuth-Morris-Pratt)算法的核心在于 利用模式串自身的重复性,通过 预处理 next 数组 来优化匹配过程,避免主串回溯,从而提升匹配效率。其关键点可总结如下:

  • 主串不回溯:传统暴力匹配在失配时主串和模式串都要回溯,而 KMP 仅调整模式串的位置,主串指针 i 始终向前移动,避免不必要的重复匹配。
  • 利用 next 数组:next[j] 表示模式串 p[0..j] 的 最长相等前后缀长度,用于在失配时快速调整模式串的匹配位置。

2、实战项目

给定主串s,字串p,求解字串在主串的位置索引。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 1e6 + 10;  // 定义足够大的数组大小
char p[N], s[N];         // p是子串,s是主串(从索引0开始存储)
int ne[N];               // next数组(部分匹配表)

int main() {
    int n, m;            
    cin >> n >> p >> m >> s;
    ne[0] = -1;

    for (int i = 1, j = -1; i < n; i ++)  // 计算next数组(KMP预处理阶段)
    {
        while (j != -1 && p[i] != p[j + 1]) j = ne[j]; // 且当前字符不匹配时,回退j到ne[j]
        if (p[i] == p[j + 1])  j++; // 如果当前字符匹配,j向后移动
        ne[i] = j; // 记录当前位置的最长相等前后缀长度
    }

    // KMP匹配阶段(在主串s中查找模式串p)
    for (int i = 0, j = -1; i < m; i++) 
    {
        while (j != -1 && s[i] != p[j + 1])  j = ne[j]; //且当前字符不匹配时,回退j到ne[j]
        // 如果当前字符匹配,j向后移动
        if (s[i] == p[j + 1])   j++;
        if (j == n - 1) 
        {  
            cout << i - j << ' ';
            j = ne[j];             // 回退j,继续寻找
        }
    }
    return 0;
}

3、难点

难点就是求解next数组,也就是匹配表。

以abcab为例:

所有前缀组合:a, ab, abc, abca;   

所有后缀组合:b, ab, cab, bcab;

可以发现前缀规律:每一个前缀的开头一定是a字符;也就是在匹配表中,如果回溯1步,那么一定是回溯到a的位置;类似的,2步应该到ab位置,3步应该到abc位置。如果当前ne[j] = 2(0,1,2匹配),那么前面两个数也是可以回溯的,也就是前面j-1, j-2索引上的数也是匹配上了的。

C++串的模式匹配(BF,KMP详解) C++串的模式匹配 在数据结构的学习过程中,继顺序表,链表,队列,栈之后的一个部分便是串。本质上串也是线性表的一种,其当然可以分为顺序存储结构与链式存储结构。它的一些接口也已经由STL中的<string.h>配备完全,需要时直接调用即可。 本文将主要介绍串的模式匹配部分,包括概念,Brute Force(BF)和KMP共三部分。因为我在学习和用C++实现KMP时,发现了诸多问题。所以本文将着重详解C++实现的KMP算法(包括生成next表)。 概念 所谓串的模式匹配,用白话讲,就是在主串(串S) 阅读详情

相关推荐

KMP算法:数据结构王道考研C++/Java实现指南

数据结构是计算机存储、组织数据的方式,它决定了数据处理的效率。本章将介绍数据结构的一些基础概念,并为理解后续章节中的KMP算法打下基础。数据结构可以定义为数据元素的集合以及它们之间的关系和定义在这些关系上的操作的集合。它主要分为两大类:线性结构和非线性结构。线性结构包括数组、链表、栈、队列等,它们的共同特点是元素之间存在一对一的关系。非线性结构包括树、图等,元素之间存在一对多的关系。时间复杂度是衡量算法效率的一个重要指标,它描述了算法执行时间随输入数据规模增长的变化趋势。

weixin_34471637的博客 1068

C++:KMP字符串详解

kmp算法(Knuth-Morris-Pratt算法)是一种算法,可以在O(m+n)的时间复杂度内实现两个字符串的匹配。下面谈谈个人对于kmp算法浅陋的理解。

qq_73176808的博客 1100

字符串处理技术:Hash, KMP, Trie, AC自动机

字符串是程序设计语言中的基本数据类型之一,是由零个或多个字符组成的有限序列。在计算机中,字符串通常以字符数组的形式存在。字符串的长度可以是固定的,也可以是动态变化的,取决于语言的实现和应用场景。在哈希技术中,冲突是指两个不同的键值在哈希函数的计算后得到了相同哈希值的情况。理想情况下,哈希函数应该为每一个可能的键值分配一个独一无二的哈希值。然而,在实际应用中,由于哈希表的大小总是有限的,冲突是无法避免的。冲突类型主要分为两大类:同义词冲突(Synonym Conflict)

weixin_35750953的博客 796

朴素字符串匹配算法与KMP算法【数据结构与算法】

本文精解从朴素到KMP的字符串匹配,阐述KMP如何用next数组消除回溯,实现线性高效查找。

不会C++、害怕嵌入式且不爱看动漫的小趴菜 1万+

LS-Dyna模态分析实战:从模型构建到结果解读的全流程指南

本文提供了一份详尽的LS-Dyna模态分析实战指南。文章系统讲解了如何利用LS-Dyna内置的隐式求解器进行特征值求解,从模型构建、几何清理、材料与连接设置,到核心的边界条件与隐式求解控制(如*CONTROL_IMPLICIT_EIGENVALUE),最后完成计算并解读频率与振型结果。旨在帮助工程师在熟悉的环境中高效完成结构振动特性分析,为后续动态响应分析奠定基础。

info6的博客 264

centos7下安装gcc-10.3.0

生成多个系统版本的代码,如果你的操作系统是32位,默认就已经设置为 disable,这时gcc仅能生成32位的可执行程序;这里只开启了c,c++ 和fortran,因为支持的语言越多,就需要安装越多的相应静态与动态库,还有五花八门的依赖库,这会让管理变得困难,体积也会变得庞大。启用posix标准的线程支持,这个设置取决于宿主或目标操作系统的类型,其它可用值有:aix,dec,solaris,win32等,如果你是其它的类UNIX系统,就需要设置相应的值。指定安装路径,这里没有指定,就直接放到文件夹里就好。

lxystar2003的博客 1189

KMP-字符串查找算法

问题:假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢?即2层循环,太过复杂。

禊月初三的博客 1447

单神经元PID控制:从Hebb到Delta,四种学习规则在MATLAB里到底怎么选?

本文深入探讨了单神经元PID控制算法在MATLAB中的四种学习规则(无监督Hebb、有监督Delta、有监督Hebb及改进Hebb)的实战对比与选型指南。通过详细的仿真实验和性能指标分析,为工程师提供了基于实际工程考量的选型建议和参数整定技巧,帮助优化复杂非线性系统的控制效果。

weixin_31220401的博客 283

KMP算法C++实现

KMP算法C++实现 KMP算法 KMP算法的核心是利用比较过的匹配失败后的信息,主串指针不需要回溯,仅将子串向后滑动一个合适的位置,并从该位置开始和主串进行比较,该位置仅取决于子串本身,利用子串获得next数组,用于失配时子串滑动,KMP通过尽量减少模式串与主串的匹配次数以达到快速匹配的目的。 在子串中求得next数组,假设在next[j]已经求得的情况下,若子串中字符tj等于ti,j为当前t最长相等前后缀长度,则next[i+1] = j+1,若tj不等于ti,将ti-j+1…ti作为主串,t1…tj作

qq_44486439的博客 2751

AT89C52单片机+LCD屏:手把手教你做一个能算小数和负数的计算器(附完整代码)

本文详细介绍了如何使用AT89C52单片机和LCD1602显示屏构建一个支持小数和负数运算的高精度计算器。从硬件选型、系统架构设计到核心算法实现,提供了完整的代码示例和优化技巧,特别适合51单片机初学者和课程设计参考。

weixin_30374009的博客 371

Android逆向实战:用Xposed Hook微信消息发送(附完整代码)

本文提供了一份Android逆向实战指南,详细讲解如何使用Xposed框架Hook微信消息发送功能。内容涵盖环境搭建、逆向分析定位关键方法、编写Hook模块代码以及调试部署的全过程,并附有完整代码示例,帮助开发者深入理解Android应用底层交互与Hook技术。

weixin_29196315的博客 1118

数据结构·KMP·笔记

数据结构·KMPKMP1.简介2.KMP使用的例子3.公共前后缀是什么?怎么找?4.next数组5.nextval数组 KMP 1.简介 KMP算法目的是在主串中快速找到一个字串 快速:并非一位一位比较后发现不匹配然后后移一位 字串:此处我们以后叫模式串 2.KMP使用的例子 红色框住是完全匹配部分,蓝色是最大公共前后缀 当字符发生不匹配时(红色框外第一对,主串B!=模式串A)开始在完全匹配部分找最大公共前后缀 下一步,将前缀移动到后缀,然后在下一个发生不匹配的字符位置之前完全匹配部分找最大公共前后缀 当模

qq_61179907的博客 1987

《Python星球日记》 第72天:问答系统与信息检索

《Python星球日记》 第72天:问答系统与信息检索,在前面的日子里,我们学习了自然语言处理的基础知识,包括文本预处理、词向量、Transformer架构和各种预训练模型。今天,我们将探索问答系统这一NLP的重要应用,以及如何结合信息检索技术构建智能问答系统。

Code_流苏:在代码中寻诗意,在实践中觅真知 1075

KMP算法详解(c++实现)

目的:在文本串S中查找一个模式串P,并返回模式串P在文本串S中的位置。思想:利用模式串P本身的性质,消除重复的比较。在BF算法中,逐个字符地比较模式串和文本串中的相应部分,我们会得到一个模式串的子串刚好与文本串匹配。BF算法的下一步是回溯到文本串上次比较的起始位置;而KMP算法则不需要回到起始位置。而是根据子串中开头与结尾字符重复的部分,让文本串比较的起始点从子串开头重复在文本串中的对应位置(前缀)移动至子串结尾重复在文本串中的对应位置(后缀)。最终使算法复杂度从O(m*n)减少到O(m+n)

watamade的博客 2289

AHB—SRAMC项目(结构图,核心代码、Testbench架构)

文章目录一、AHB_SRAMC项目介绍1.1.AHB总线控制单元(ahb_slv_if.v)1.2.SRAM控制单元(sramc_top.v)1.3.主要的传输路径二、结构框图2.1.AHB_SRAMC结构图(重点)2.2.总线控制单元与SRAM控制单元结构图三、部分核心代码(重点理解)四、SystemVerilog Testbench架构(重点)五、目录结构 一、AHB_SRAMC项目介绍 本项...

Mr.翟的博客 3万+

Docker-Nvidia(NVIDIA Container Toolkit)

安装NVIDIA Container Toolkit工具,支持docker使用GPU。

周陽讀書 3821

实验二:使用KMP算法实现字符串的匹配

1.实验目的 熟练的掌握数据结构中串这种数据类型;学会使用相较于朴素的模式识别算法更加先进的KMP算法进行识别和匹配。 同时,在数据结构试验之中熟悉和了解串的性质和使用方法。 2.实验要求 输入:通过命令行参数输入原字符串和模式字符串。 输出: (1)命令行参数不正确输出字符串ERROR_01; (2)如果查找到模式串,输出关键字在字符串中的位置(计数从1开始); (3)如果未找到模式串则输出-1 。 实例: 输入:“select * ...

m0_55952025的博客 2947

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C++ : KMP 字符串匹配算法

在传统字符串匹配中我们求得字符串p出现在字符串s中的位置。我们把字符串s称为主串,字符串p称为模式串。 KMP算法的原理简单来说就是匹配的时候不回溯主串的指针i,而只回溯模式串指针j ,即匹配过程中,不移动主串,指移动模式串来达到"尽可能向右滑动最大的距离"。 num 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

superSmart_Dong的博客 592

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

字符串处理——KMP

字符串处理——KMP模板 代码 //查找模式串在母串的出现次数 #include<stdio.h> #include<iostream> #include<string.h> using namespace std ; const int maxn = 1e6+5; int Next[maxn]; char str[maxn];//母串 char mo[max...

SCUEC__zhazhahui的博客 232

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

KMP算法的原理和C++实现

前言 最近在实践费曼学习法,将其运用于学习中。kmp算法是数据结构与算法中一个艰难的知识点,弄懂这个算法的原理并使用C++实现耗费了数天时间。这篇博客梳理了KMP算法的原理和我C++实现算法思路。 简介 KMP算法是基于BF算法的优化算法,BF算法是将主串分解成(主串长度-模式串长度+1)个子串,再一一比较这些子串和模式串,每次比较都要回溯主串的指针,而KMP算法就是在回溯部分进行了优化,主串指针不进行回溯,而是回溯模式串的指针到特定的位置继续匹配,KMP算法的关键部分就是在与寻找模式串回溯的特定位置

m0_51909863的博客 1365

字符串模式匹配(KMP)

字符串模式匹配(KMP) 给定一个字符串 text 和一个模式串 pattern,求 pattern 在text 中的出现次数。text 和 pattern 中的字符均为英语大写字母或小写字母。text中不同位置出现的pattern 可重叠。 输入格式: 输入共两行,分别是字符串text 和模式串pattern。 输出格式: 输出一个整数,表示 pattern 在 text 中的出现次数。 输入样...

黄大仙 2404

算法基础_数据结构【KMP + Trie 树 + 并查集】

本篇博客是《算法基础_数据结构》的算法题型总结+模板习题练习。主要算法涉及:KMP、Trie树、并查集的算法。

序属秋秋秋的博客 1363

KMP 字符串匹配算法

参考了一个大佬的java 代码,改成了C++版本并可以处理文本中重复出现模式串的情况。 代码如下: #include <iostream> #include <vector> #include <string> using namespace std; class KMP { string pat; vector<vector<...

王学门徒 240

KMP 字符串搜索算法的c++实现

说明: KMP 字符串搜索算法是基于自动状态机的高效搜索算法假如被搜索的字符串(长串)长度为 n, 要搜索的字符串(字串)长度为 m,则其空间复杂度为 O(m),时间复杂度为 O(n+m)由于该算法是基于自动状态机的,对于字符串分布在不同位置的时的处理较简单(某些公司面试题不是要在不连续内存中搜索字符串嘛,可以用kmp算法简单实现哦,不用考虑字符串拼接啊,中间复杂状态处理之类的)

景奇的专栏 1077

c++ kmp算法字符匹配_一文读懂字符串之 KMP 算法

以前的计算机刚被发明的时候,主要作用是做一些科学和工程的计算工作,科学家发明计算机的时候压根儿不可能想到后人还可以用来KMP。刚开始的计算机都是处理数值工作,后来引入了字符串的概念,计算机开始可以处理非数值的概念了(当然原理还是用数值来模拟非数值,通过ASCII码表)。总之在工作当中字符串的处理操作非常普遍,今日主要分享字符串模式匹配算法KMP的相关操作。在分享KMP算法之前,我们先看一...

weixin_39805355的博客 111

数据结构第一弹-字符串处理

在不同的编程语言中,字符串的内部表示方式可能有所不同,但大多数现代语言都支持Unicode编码,以适应全球多种语言的需求。KMP算法是一种高效的字符串匹配算法,其核心思想是利用已经部分匹配的信息避免重复计算。字符串处理是计算机科学领域的一个重要课题,涉及到许多复杂的算法和技术。暴力法是最直接的字符串匹配方法,它通过逐个字符比较的方式找到子串的位置。简单的字符串压缩可以通过统计连续相同字符的数量来实现。

fengxiaotao_cool的专栏 826
上一篇: C++数据结构6:滑动窗口
下一篇: C++数据结构8:并查集
桑乔
博客等级 码龄5年 85粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值