【KMP算法】C++

news2024/10/6 20:40:07

KMP算法的原理是通过构建部分匹配表,来利用已经匹配过的信息,避免不必要的回溯。部分匹配表是一个长度与模式字符串相等的数组,用于记录在每个位置上的最长公共前后缀的长度。

在这里插入图片描述
这样图片完全表达了KMP算法的核心思想,出处来自添加链接描述

大家如果还看不懂可以结合以下代码来理解:

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

// 构建部分匹配表
vector<int> buildPartialMatchTable(const string& pattern) {
    int m = pattern.length();
    vector<int> table(m, 0);
    int len = 0;
    int i = 1;

    while (i < m) {
        if (pattern[i] == pattern[len]) {
            len++;
            table[i] = len;
            i++;
        }
        else {
            if (len != 0) {
                len = table[len - 1];
            }
            else {
                table[i] = 0;
                i++;
            }
        }
    }
    for (int i = 0; i < table.size(); i++) {
        cout << table[i];
    }
    cout << endl;
    return table;
}

// 使用 KMP 算法查找子字符串
void searchKMP(const string& text, const string& pattern) {
    int n = text.length();
    int m = pattern.length();
    vector<int> table = buildPartialMatchTable(pattern);
    int i = 0, j = 0;

    while (i < n) {
        if (pattern[j] == text[i]) {
            i++;
            j++;
        }

        if (j == m) {
            cout << "在位置 " << i - j << " 处找到匹配" << endl;
            j = table[j - 1];
        }
        else if (i < n && pattern[j] != text[i]) {
            if (j != 0) {
                j = table[j - 1];
            }
            else {
                i++;
            }
        }
    }
}

int main() {
    string text = "ABABDABACDABABCABAB";
    string pattern = "ABABCABAB";

    cout << "在文本中查找子字符串:" << endl;
    searchKMP(text, pattern);

    return 0;
}

先不管逻辑,我们先看程序输出:

在文本中查找子字符串:
001201234
在位置 10 处找到匹配

001201234,为什么是这段代码,结合着上面的图片:
在这里插入图片描述
在部分匹配表中,每个索引位置的值表示在该位置之前的最长公共前后缀的长度。代码中的查找字符串为ABABCABAB对应索引位置为

索引位置 i:  0 1 2 3 4 5 6 7 8
部分匹配值:  0 0 1 2 0 1 2 3 4

这样就能够知道遇到不同的字母时需要跳转的路径。

代码逻辑:buildPartialMatchTable函数用于构建部分匹配表。函数接受一个模式字符串作为参数,返回一个部分匹配表。该函数使用两个指针i和len,其中i从1开始,len初始化为0。通过遍历模式字符串,来逐个计算每个位置上的最长公共前后缀长度。具体步骤如下:

如果当前位置的字符和前缀的下一个字符相等,那么len加1,table[i]等于len,然后指针i和len都向后移动一位。
如果当前位置的字符和前缀的下一个字符不相等,那么判断len是否为0。如果len不为0,将len更新为前一个位置的最长公共前后缀长度,然后继续比较当前位置的字符和前缀的下一个字符。如果len为0,表示当前位置没有最长公共前后缀,将table[i]设为0,然后指针i向后移动一位。
最后,返回构建好的部分匹配表。
然后,searchKMP函数用于在文本字符串中查找子字符串。函数接受一个文本字符串和一个模式字符串作为参数,不返回值。函数内部使用两个指针i和j,其中i表示在文本字符串中的位置,j表示在模式字符串中的位置。具体步骤如下:

当模式字符串和文本字符串的字符相等时,指针i和j都向后移动一位。
当j等于模式字符串的长度m时,表示找到了匹配,输出匹配的位置i-j,并将指针j更新为部分匹配表中的值table[j-1],继续查找下一个匹配。
当i小于文本字符串的长度n且j不等于模式字符串的长度m时,如果当前位置的字符和模式字符串的字符不相等,那么判断j是否为0。如果j不为0,将j更新为部分匹配表中的值table[j-1],然后继续比较当前位置的字符和模式字符串的字符。如果j为0,表示当前位置没有匹配,将指针i向后移动一位。

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

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

相关文章

【postgresql】ERROR: cannot alter type of a column used by a view or rule

修改字段类型 由varchar 改为int8。 具体sql alter table company alter column city_id type int8 using city_id::int8; 返回错误信息 > ERROR: cannot alter type of a column used by a view or rule DETAIL: rule _RETURN on view search_qy depends on column …

什么是LIMS(实验室信息管理系统)?LIMS软件有哪些功能?

LIMS 是实验室信息管理系统&#xff08;Laboratory Information Management System&#xff09;的缩写。LIMS 是一种软件&#xff0c;它可以帮助实验室收集、组织和跟踪其数据。这种系统可以提高实验室的效率&#xff0c;同时确保数据的准确性和一致性。 LIMS 可以处理各种实验…

安装Python3.x--Windows

1 下载安装包 确定安装是干什么&#xff0c;要下哪个版本&#xff08;如果是配置项目环境&#xff0c;最好按项目需求的版本来装&#xff09; 1.1 官网链接 https://www.python.org 最新版本 指定版本 2 安装说明 点击下载exe&#xff0c;运行自定义安装路径&#xff0c;下…

go字符串拼接方式及性能比拼

在golang中字符串的拼接方式有多种&#xff0c;本文将会介绍比较常用的几种方式&#xff0c;并且对各种方式进行压测&#xff0c;以此来得到在不同场景下更适合使用的方案。 文章目录 1、go字符串的几种拼接方式1.1 fmt.Sprintf1.2 运算符拼接1.3 strings.Join1.4 strings.Bui…

使用redis实现分布式锁

为什么需要分布式锁 在一个分布式系统中&#xff0c;也会涉及多个节点访问同一个公共资源的情况&#xff0c;此时就需要通过锁来做互斥控制&#xff0c;避免出现类似于“线程安全”的问题&#xff0c;而java的synchronized这样的锁只能在当前进程中生效&#xff0c;在分布式的…

【Go】Golang环境配置与语法基础

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Golang环境配置与示例。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路…

【Pycharm/Anaconda配置环境记录】

文章目录 1、Pytorch配置2、mmcv配置 1、Pytorch配置 查看虚拟环境创建虚拟环境 conda env list&#xff1a;查看虚拟环境 conda create --name env_name python3.7&#xff1a;创建虚拟环境 conda activate env_name&#xff1a;激活/进入该虚拟环境 查看自己的CUDA版本以及P…

element-plus-自定义Dialog样式

实现如下 <template><h3>dialog3 test 全局</h3><el-button type"primary" size"default" click"show">全局弹窗</el-button><div class""><!-- 弹窗 --><el-dialog v-model"visi…

使用 Matter-SDK 快速搭建 Matter 环境 (Linux)

Matter 作为一个统一的智能家居互联协议&#xff0c;凭借其高兼容性的特点&#xff0c;正逐渐打破各个智能家居之间的壁垒。乐鑫作为在 Matter 项目发布之初的早期成员&#xff0c;提供了一套开源、完整、易用的 Matter-SDK。 乐鑫的 Matter-SDK 是建立在开源 Matter-SDK 之上…

MySQL - order by排序查询 (查询操作 四)

功能介绍&#xff1a;order by&#xff1a;对查询结果进行排序&#xff0c;执行顺序在查询完结果执行&#xff08;比如where后&#xff09; 排序方式&#xff1a;ASC&#xff1a;升序&#xff08;默认&#xff0c;不用指定&#xff09; DESC&#xff1a;降序 语法&#x…

Android跨进程通信:Binder机制原理

目录 1. Binder到底是什么&#xff1f; 2. 知识储备 2.1 进程空间划分 2.2 进程隔离 & 跨进程通信&#xff08; IPC &#xff09; 2.3 内存映射 2.3.1 作用 2.3.2 实现过程 2.3.3 特点 2.3.4 应用场景 2.3.5 实例讲解 ① 文件读 / 写操作 ② 跨进程通信 3. Bi…

【Java 基础篇】Java 图书管理系统详解

介绍 图书管理系统是一种用于管理图书信息、借阅记录、用户信息等的软件系统。它可以帮助图书馆、书店或个人管理和组织图书资源&#xff0c;提供了方便的借阅和查询功能。在这篇博客中&#xff0c;我们将详细介绍如何使用Java编程语言创建一个简单的图书管理系统。 功能需求…

SpringMVC 学习(一)Servlet

1. Hello Servlet (1) 创建父工程 删除src文件夹 引入一些基本的依赖 <!--依赖--> <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test<…

大模型lora微调-chatglm2

通义千问大模型微调源码&#xff08;chatglm2 微调失败&#xff0c;训练通义千问成功&#xff09;&#xff1a;GitHub - hiyouga/LLaMA-Efficient-Tuning: Easy-to-use LLM fine-tuning framework (LLaMA-2, BLOOM, Falcon, Baichuan, Qwen, ChatGLM2)Easy-to-use LLM fine-tun…

STM32存储左右互搏 I2C总线读写FRAM MB85RC1M

STM32存储左右互搏 I2C总线读写FRAM MB85RC1M 在较低容量存储领域&#xff0c;除了EEPROM的使用&#xff0c;还有铁电存储器FRAM的使用&#xff0c;相对于EEPROM, 同样是非易失性存储单元&#xff0c;FRAM支持更高的访问速度&#xff0c; 其主要优点为没有EEPROM持续写操作跨页…

day06_循环

今日内容 零、 复习昨日 一、循环 二、流程控制关键词 零、 复习昨日 8个基本数据类型 变量的使用步骤 1)声明2)赋值3)使用 声明,数据类型 变量名 不一定非得是基本类型 int a; String s; Scanner scanner;赋值,只要符合类型(能默认转换)就能赋值 int a 1; double d 1; Scann…

uni-app问题记录

一、启动问题记录 1. 报错1 解决办法: 开启微信开发者工具服务端口 2. 报错2:调用getLocation获取位置信息时报错以下内容 {errMsg: “getLocation:fail the api need to be declared in the requiredPrivateInfos field in app.json/ext.json”} 解决办法: manifest.json文…

到广阔的边缘市场去,浪潮信息首次发布全栈边缘计算软硬件新品

出品 | CSDN 云计算 智慧时代&#xff0c;一切皆计算&#xff0c;早已不再是一句口号。据国际研究机构 IDC 数据显示&#xff0c;2023 年超过 50%的企业新增 IT 基础设施会部署在边缘&#xff0c;而 Gartner 研究显示&#xff0c;到 2025 年&#xff0c;超过 75%的数据生成和数…

【ROS入门】使用 ROS 服务(Service)机制实现同步请求与答复

文章结构 任务要求话题模型实现步骤自定义srv定义srv文件编辑配置文件编译 自定义srv调用vscode配置编写服务端实现编写客户端实现 执行启动roscore编译启动客户端和服务端编译启动roscore启动节点 任务要求 编写代码实现 ROS 中的服务请求与答复: 创建服务端&#xff0c;注册…

vue中使用富文本编辑器,@tinymce/tinymce-vue

富文本就是在后台管理系统中常见的录入带格式的内容&#xff0c;如&#xff1a;表格&#xff0c;字体加粗&#xff0c;斜体&#xff0c;文字颜色等等&#xff0c;就像一个word一样。类似于这样的效果&#xff1a; 我们使用通用在线编辑器tinymce。支持vue和react。 1. 安装 np…