【数据结构】模式匹配之KMP算法与Bug日志—C/C++实现

🌈个人主页:Sarapines Programmer
🔥 系列专栏:《数据结构奇遇记》
🔖墨香寄清辞:墨痕寄壮志,星辰梦未满。 通幽径心凝意,剑指苍穹势如山。

目录


🌞1. 模式匹配的基本概念

🌞2. 模式匹配的解决办法

🎈2.1 暴力匹配(BF)算法

🎈2.2 KMP算法

🤖2.3 BUG记录_KMP算法


🌞1. 模式匹配的基本概念

1.1 模式匹配是在字符串 s (称为目标串)中寻找字符串 t (称为模式串)的过程。

  1. 目标串: 这是要进行搜索的字符串,包含了我们需要查找模式的信息。

  2. 模式串: 这是要在文本串中寻找的具体字符串或子字符串。

示例:目标串s="aaaaab",模式串t="aaab".

1.2 常见的模式匹配算法

  • 暴力匹配(BF)算法: 从文本串的第一个字符开始,逐一与模式串比较,如果不匹配,则移动到下一个位置。

  • KMP算法: 通过预处理模式串,构建一个部分匹配表next[],利用已匹配的信息来避免不必要的比较,提高匹配效率。


🌞2. 模式匹配的解决办法

🎈2.1 暴力匹配(BF)算法

从头开始遍历寻找,若不匹配则主串的指针i返回,从下一个地址开始(i-j+1)

简单示例:目标串s="aaaaab",模式串t="aaab".若成功返回匹配成功的位置,否则返回0.

#include <iostream>
#include <string>
using namespace std;

int BF(string s,string t){
    int i=0,j=0;
    while(i<s.length() && j<t.length()){
        if(s[i]==t[j]){
            i++;
            j++;
        }
        else{
            i=i-j+1;
            j=0;
        }
    }
    if(j>=t.length()) return (i-t.length());
    else return (-1);
}

int main(){
    string s1,s2;
    getline(cin,s1);//helloworld
    getline(cin,s2);//wo

    cout<<BF(s1,s2)<<endl;

    return 0;
}

🎈2.2 KMP算法

基本步骤:

  1. 构建部分匹配表: KMP算法的核心是在匹配失败时能够利用已匹配的信息,避免重复比较。

  2. 匹配过程: 在匹配过程中,通过部分匹配表的信息来实现跳过一定的比较。

注意:不要直接使用str.length()    做个转换再用  int slen=str.length();

简单示例:目标串s="aaaaab",模式串t="aaab".若成功返回匹配成功的位置,否则返回0.

#include <iostream>

using namespace std;

/********模式识别**********/
//方法一:暴力搜索
void BF(string s,string t){
    int i=0,j=0;
    int slen=s.length(),tlen=t.length();

    for(;i<slen && j<tlen;){
        if(s[i]==t[j]){
            i++;j++;
        }
        else{
            i=i-j+1;
            j=0;
        }
    }

    if(j>=tlen) cout<<"暴力搜索模式匹配成功,"<<t<<"处于"<<s<<"的第"<<i-tlen+1<<"位"<<endl;
    else cout<<"暴力搜索模式匹配失败"<<endl;
}

//方法二:KMP算法
void getNext(string t,int *next){
    int j=0,k=-1;
    next[0]=-1;
    while(j<t.length()){
        if(k==-1 || t[k]==t[j]){
            j++;k++;
            next[j]=k;
        }
        else k=next[k];
    }
}

void KMP(string s,string t){
    int slen=s.length(),tlen=t.length();
    int i=0,j=0;

    int *next=new int[tlen];
    getNext(t,next);
    while(i<slen && j<tlen){
        if(j==-1 || s[i]==t[j]){
            i++;j++;
        }
        else j=next[j];
    }
    delete [] next;
    if(j>=tlen) cout<<"KMP算法模式匹配成功,"<<t<<"处于"<<s<<"的第"<<i-tlen+1<<"位"<<endl;
    else cout<<"KMP算法模式匹配失败"<<endl;
}

int main(){
    string s,t;
    getline(cin,s);
    getline(cin,t);

    //暴力搜索
    BF(s,t);

    //KMP
    KMP(s,t);
    return 0;
}

🤖2.3 BUG记录_KMP算法

千万不要小看一个小小的bug会毁我大几小时的宝贵时光!!!

错误示例:
for(int i=0;i<s.length();i++){...}//s为string类型

解决方案:
int slen=s.length();
for(int i=0;i<slen;i++){...}

上述用例我相信很多人经常这样用却并没有出错,但是在下面的案例错误就十分明显。因为在

测试用例【1为目标串,2为模式串】

  1. helloworld
  2. wo

中返回的【i-t.length()】值一个为 0 (显然是错的),一个为 5.

错误示例:【正确示例见章节2.2】

#include <iostream>
#include <string>
using namespace std;

/*KMP算法*/
//求next[]
void getNext(string t,int next[]){
    int j=0,k=-1;//j扫描t,k记录t[j]之前与t首字符相同的个数
    next[0]=-1;
    for(;j<t.length();){//next[0]已经给了,剩下的t.length()-1
        if(k==-1 || t[j]==t[k]){
            j++;k++;
            next[j]=k;
        }
        else k=next[k];
    }
}

//KMP
int KMP(string s,string t){
    int *next=new int[t.length()];
    getNext(t,next);

    int i=0,j=0;
    while(i<s.length() && j<t.length()){
        if(j==-1 || s[i]==t[j]){
            i++;
            j++;
        }
        else{
            j=next[j];
        }
    }

    delete [] next;
    
    if(j>=t.length()) return (i-t.length());
    else return (-1);
}

int main(){
    string s1,s2;
    getline(cin,s1);//helloworld
    getline(cin,s2);//wo

    cout<<KMP(s1,s2)<<endl;

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/255895.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Scala多线程爬虫程序的数据可视化与分析实践

一、Scala简介 Scala是一种多种类型的编程语言&#xff0c;结合了针对对象编程和函数式编程的功能。它运行在Java虚拟机上&#xff0c;具有强大的运算能力和丰富的库支持。Scala常用于大数据处理、并发编程和Web应用程序开发。其灵活性和高效性编程成为编写多线程爬虫程序的理…

科技云报道:至简至强,新一代服务器的算力美学

科技云报道原创。 在这个时代&#xff0c;数据和计算的边界正在迅速扩张。 随着云计算、物联网和人工智能的日益成熟&#xff0c;对算力的需求已经突破了传统的限制&#xff0c;进入了一个全新的阶段。在这个阶段&#xff0c;不仅是算力的量级发生了变化&#xff0c;其性质和…

Mysql之约束上篇

Mysql之约束上篇 约束的概述为什么需要约束什么是约束约束的分类 非空约束作用关键字特点添加非空约束删除非空约束 唯一性约束关键字特点添加唯一约束关于复合唯一约束删除唯一约束查看索引 主键约束(非空唯一性约束)作用关键字特点添加主键约束关于复合主键删除主 约束的概述…

【MYSQL】-库的操作

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

[单片机软件]1.keil调整Group中的位置挪动

1.找到并选择箭头所指图标&#xff1a; 2.选中箭头所指进行你想要的Group进行移动 以上均为实测有效。

百度云IOCR自定义模版分类器进行文字识别(非通用文字识别)

模版管理 云账号登录 访问模版管理地址&#xff1a;点击下面地址新建模版 百度智能云-登录https://ai.baidu.com/iocr?castk4819agr76c7d09971d248#/templatelist/1 添加模版 如果有模版&#xff0c;识别效果不理想可以编辑上述模版&#xff0c;如果新的报表格式可以新建模…

如何访问AWS私有网络中的RDS (Mysql)

文章目录 小结问题及解决连接问题如何使用本地的Mysql Workbench对RDS进行访问 参考 小结 在AWS私有网络中部署了RDS (Mysql), 尝试通过外网成功地进行了访问. 问题及解决 连接问题 在AWS私有网络中部署了RDS (Mysql), 进行外网进行访问碰到了各种问题. 以下连接超时&…

【05】GeoScene海图或者电子航道图批量出图

出单张000数据参考上一篇博客&#xff0c;如果想同时出多张海图000数据&#xff0c;也是可以实现的。思路如下&#xff1a; 1 批量创建产品 GeoScene海事模块通过ProductDefinitions表和ProductCoverage要素类定义产品和AOI覆盖区&#xff0c;可支持批量导入产品信息和AOI覆盖…

@RequestMapping注解与其派生注解接收参数详解

一、前言 根据 HTTP 标准&#xff0c;HTTP 请求可以使用多种请求方法。 HTTP1.0 定义了三种请求方法&#xff1a; GET, POST 和 HEAD 方法。 HTTP1.1 新增了六种请求方法&#xff1a;OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。 RequestMapping注解与其派生注解 在…

网络环境搭建及uboot配置

网络环境搭建 搭建网络环境可以搭建公网的也可以搭建局域网的&#xff0c;这里搭建的是局域网的。 详细看实验手册第一个实验 系统移植实验手册 linux内核的安装与加载 这一章节主要分为两大块&#xff1a;一个为产品阶段即&#xff1a;Linux内核、根文件系统、uboot全部存储到…

董宇辉“小作文事件”:东方甄选的危机与挑战

导言 近期&#xff0c;东方甄选公司的创始人董宇辉因涉及“小作文事件”而引起轩然大波。东方甄选作为一家在招聘领域崭露头角的公司&#xff0c;经历了充满曲折的发展历程。本文将深入探讨这一事件对东方甄选公司的发展带来的危机和挑战&#xff0c;以及公司可能采取的解决策略…

AI绘画中UNet用于预测噪声

介绍 在AI绘画领域中&#xff0c;UNet是一种常见的神经网络架构&#xff0c;广泛用于图像相关的任务&#xff0c;尤其是在图像分割领域中表现突出。UNet最初是为了解决医学图像分割问题而设计的&#xff0c;但其应用已经扩展到了多种图像处理任务。 特点 对称结构&#xff1a…

详细教程 - 从零开发 鸿蒙harmonyOS应用 第九节-——鸿蒙操作系统中的自定义视图封装:一次奇妙的旅程

一、简介 自定义视图是开发鸿蒙应用时的一个重要功能。在这篇文章中&#xff0c;我们将详细探讨如何在鸿蒙系统中实现自定义视图的封装&#xff0c;并提供一些代码示例作为你的地图。 二、自定义视图的实现 在鸿蒙操作系统中&#xff0c;我们可以通过继承ohos.agp.components.…

【Hadoop】HDFS的体系架构

整体上说HDFS框架结构一HDFS框架结构二&#xff08;HDFS High Availability&#xff09; 整体上说 HDFS 采用 Master/Slave 架构。一个 HDFS 集群是由一个 NameNode 和一定数目的 DataNodes组成。其中 NameNode 是一个中心服务器&#xff0c;负责文件系统的名字空间(namespace…

【Docker】Docker安装部署maven私服

文章目录 镜像拉取构建nexus实例登录maven私服如何查看实例初始化的admin密码呢&#xff1f;1.查看容器挂载卷2.找到nexus_nexus_data查看挂载卷详情3.查看admin账号密码4.登录并重置密码 使用nexus私服1.设置settings.xml2.设置idea pom 出现的问题小插曲 镜像拉取 docker pu…

DVWA靶场的设置

1).在win 10系统安phpstudy2016&#xff0c;如图所示 2&#xff09;创建DVWA的靶场&#xff0c;解压DVWA-master.zip到C:\phpStudy\WWW\DWA-master 3&#xff09;配置DVWA链接数据库 右键选择记事本打开configlconfig.inc.php.dist【也可以使⽤其他编辑⼯具打开】&#xff0c;…

react基于antd二次封装spin组件

目录 react基于antd二次封装spin组件组件使用组件效果 react基于antd二次封装spin组件 组件 import { Spin } from antd; import propTypes from "prop-types"; import React from react; import styleId from "styled-components"; // 使用 父div必须加…

【vtkWidgetRepresentation】第十四期 二维标注

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享vtk中的二维标注,主要用于医学领域,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 目录 前言 1. vtkBiDimension…

LVS-DR部署

目录 LVS的工作模式及其工作过程 NAT模式&#xff08;VS-NAT&#xff09; 直接路由模式&#xff08;VS-DR&#xff09; IP隧道模式&#xff08;VS-TUN&#xff09; DR模式 LVS负载均衡群集的分析及特点 数据包流向分析 DR 模式的特点 LVS-DR部署实例 LVS-DR模式部署流…

主从reactor多线程实现

现场模型图片&#xff0c;从网上找的 出于学习的目的实现的&#xff0c;如有不对的地方欢迎留言知道&#xff0c;简单实现了http的请求&#xff0c;可通过postman进行访问 启动项目&#xff1a; 返回数据示例 postman请求 附上源码&#xff0c;有问题直接看源码吧