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

news2024/11/25 4:31:18

🌈个人主页: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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工作:三菱PLC程序开发流程总结

工作&#xff1a;三菱PLC程序开发流程总结 一、程序流程图 程序流程图是逻辑思维与动作流程的检查图&#xff0c;是保证逻辑思维合理的前提&#xff0c;写代码丢失方向可从程序流程图重新整理&#xff0c;程序流程图非常重要。 二、组态配置 组态配置是将所用到的基板和模块…

网络编程二

前言 在上一篇关于网络协议的博客中&#xff0c;我们简单概括了网络套接字中的UDP协议&#xff0c;本篇博客我们将继续学习分享关于网络套接字中另一个协议&#xff0c;TCP网络协议 一、UDP和TCP协议区别是什么&#xff1f; 二者之间的区别如下 &#x1f517;UDP的主要特点 …

Mysql查询使用group_concat函数后,如果查询无结果,仍会返回一条空数据

1、在查询中使用了group_concat 函数&#xff0c;简单例子如下&#xff1a; select GROUP_CONCAT(recordid) from s_au_user where username 121212此sql查询一个username 为121212的数据&#xff0c;当然肯定是查询不到的&#xff0c;理论上应该返回0条结果&#xff0c;但是…

Python操作Word

Python操作Word 一、Word简介二、向Word写入内容2.1 导入模块2.2 创建doc文档对象2.3 添加段落2.4 添加列表2.5 添加图片2.6 保存文件 三、读取Word内容四、批量生成Word文件 一、Word简介 ​ 在日常工作中&#xff0c;有很多简单重复的劳动其实完全可以交给Python程序&#x…

Camtasia2024下载安装使用教程汇总

Camtasia Studio2024提供了强大的屏幕录像(Camtasia Recorder)、视频剪辑和编辑(Camtasi Studio)、视频菜单制作(Camtasia MenuMaker)等功能&#xff0c;界面简洁明晰、操作方便快捷。使用Camtasia Studio官方用户可以方便地进行屏幕操作的录制和配音、视频的剪辑和过场动画、添…

晚期食管癌肿瘤治疗线程分类

文章目录 1、肿瘤治疗的线数1.1 基础概念1.2 线程定义1.3 如何计算治疗线数 2 食管癌治疗指南2.1 食管癌诊疗指南2.1 CSCO 本文前半部分主要来源于参考文件1&#xff0c;其余部分来源于官方指南。无原创内容&#xff0c;全部为摘要。 1、肿瘤治疗的线数 1.1 基础概念 抗肿瘤药…

【Hive】——DML

1 Load&#xff08;加载数据&#xff09; 1.1 概述 1.2 语法 LOAD DATA [LOCAL] INPATH filepath [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1val1, partcol2val2 ...)]LOAD DATA [LOCAL] INPATH filepath [OVERWRITE] INTO TABLE tablename [PARTITION (partcol…

ABAP与HANA集成 2:ABAP调用HANA存储过程或SQL语句

作者 idan lian 如需转载备注出处 需求 虽然是做BW模块&#xff0c;但是最近项目上种种&#xff0c;都需要给ABAP人员或者前台用户提供能供他们使用的表&#xff0c;就稍微研究了下ABAP和HANA的集成问题&#xff0c;因为我们BW更擅长的还是HANA&#xff0c;而且HANA的运行效…

什么是 DDoS ?如何识别DDoS?怎么应对DDOS攻击

什么是DDOS攻击 DDoS攻击&#xff08;Distributed Denial of Service Attack&#xff09;即分布式拒绝服务攻击&#xff0c;是一种利用分布式网络来发起大量的请求&#xff0c;占用目标服务器或网络资源的攻击行为。这种攻击方式可以瘫痪目标系统&#xff0c;导致其无法正常提供…

TensorFlow 2 和 Keras 之间的区别总结

1、什么是TensorFlow 2 TensorFlow 2是谷歌开源的一款深度学习框架&#xff0c;于2019年发布&#xff0c;并且在同年10月1日发布了TensorFlow 2.0.0正式稳定版。这款框架被很多企业与创业公司广泛用于自动化工作任务和开发新系统。 TensorFlow 2在分布式训练支持、可扩展的生…

MATLAB - 使用 MPC Designer 线性化 Simulink 模型

系列文章目录 前言 本主题介绍如何使用 MPC Designer 对 Simulink 模型进行线性化。为此&#xff0c;请从包含 MPC 控制器块的 Simulink 模型打开该应用程序。本例中使用 CSTR_ClosedLoop 模型。 open_system(CSTR_ClosedLoop) 在模型窗口中&#xff0c;双击 MPC 控制器模块。…

了解 SBOM (软件物料清单)

近年来&#xff0c;开源软件在开发中的采用激增&#xff0c;目前已占已构建软件的高达 90%。它在全球公司中的受欢迎程度源于成本节约和产品上市时间的加快。然而&#xff0c;在集成开源软件组件时&#xff0c;有一个关键的方面需要考虑。 Synopsys 报告84% 的商业和专有代码库…

未来十年,人工智能就业方向及前景如何?

人工智能&#xff08;AI&#xff09;是一个快速发展的领域&#xff0c;对于未来的就业方向和前景有着巨大的影响。以下是一些可能的发展趋势和就业前景&#xff1a; 1、增长趋势&#xff1a;人工智能正在全球范围内经历巨大的增长&#xff0c;预计在未来十年内将继续保持这一趋…

rn报错 run react-native-start,rn真机报错bug解决

错误信息 这个问题是因为手机和电脑没有链接起来需要实行通讯 ADB ADB (Android Debug Bridge) &#xff0c;译作 安卓调试桥 &#xff0c;一个能让你 与Android设备进行通信 的 命令行工具 。 你可以通过它&#xff0c;在命令行输入命令控制Android设备&#xff0c;或者查看…

【map】【单调栈 】LeetCode768: 最多能完成排序的块 II

作者推荐 【贪心算法】【中位贪心】.执行操作使频率分数最大 涉及知识点 单调栈 排序 map 区间合并 题目 给你一个整数数组 arr 。 将 arr 分割成若干 块 &#xff0c;并将这些块分别进行排序。之后再连接起来&#xff0c;使得连接的结果和按升序排序后的原数组相同。 返回…

【Spring】11 EnvironmentAware 接口

文章目录 1. 简介2. 作用3. 使用3.1 创建并实现接口3.2 配置 Bean 信息3.3 创建启动类3.4 启动 4. 应用场景总结 Spring 框架为开发者提供了丰富的扩展点&#xff0c;其中之一就是 Bean 生命周期中的回调接口。本文将着重介绍一个与环境&#xff08;Environment&#xff09;相关…

uniapp 预览图片

preImg(index){let urls []this.images.map((item,i) > {if(indexi){urls.unshift(item.file_path)}else{urls.push(item.file_path)}})uni.previewImage({urls})}

探索关系:Python中的Statsmodels库进阶

目录 写在开头1. 多元线性回归场景介绍 2. Logistic回归2.1 Logistic回归的概念2.2 应用案例2.2.1 建立模型和预测2.2.2 模型结论2.2.3 模型优化 3. 时间序列分析3.1 时间序列分析中的应用3.2 利用Statsmodels进行简单的时间序列分析 写在最后 写在开头 在数据分析的旅程中&am…

【react】原理简介

一、setState() 的说明 1.1 更新数据 setState() 是异步更新数据的注意&#xff1a;使用该语法时&#xff0c;后面的 setState() 不要依赖于前面的 setState()可以多次调用 setState() &#xff0c;只会触发一次重新渲染 1.2 推荐语法 推荐&#xff1a;使用 setState((sta…

C++内存布局

温故而知新&#xff0c;本文浅聊和回顾下C内存布局的知识。 一、c内存布局 C的内存布局主要包括以下几个部分&#xff1a; 代码段&#xff1a;存储程序的机器代码。.数据段&#xff1a;存储全局变量和静态变量。数据段又分为初始化数据段&#xff08;存储初始化的全局变量和…