c++ 实现KMP算法

使用C++实现KMP算法

KMP算法,全称为Knuth-Morris-Pratt算法,是一种快速匹配字符串的算法,常用于查找一个字符串在另一个字符串中的出现位置。本文将详细讲解如何使用C++实现KMP算法。

KMP算法的思路

KMP算法的核心思想是在匹配字符串时,尽可能减少比较的次数,从而提高匹配效率。具体来说,KMP算法利用匹配字符串中前缀和后缀的相似性,在匹配时通过一个模式串的“状态机”指引从而大幅减少比较的次数。

下面是KMP算法的主要流程:

  1. 初始化,设置两个指针i,j指向模式串p的第一个字符;
  2. 从左向右依次比较主串s中的每个字符和p中的对应字符;
  3. 当模式串p中第j个字符与主串s中的第i个字符相等时,则i,j同时后移;
  4. 当模式串p中第j个字符与主串s中的第i个字符不相等时,需要根据p中已匹配部分的“前缀”和“后缀”来决定下一步匹配的位置,具体而言:①当j==0时,i向右移动一位;②当j!=0时,j跳到p的前j-1个字符组成的子串中最长的“前缀”和“后缀”相等的位置的下一个位置,即j=next[j-1];
  5. 当模式串p中所有字符均已匹配,则匹配成功,返回i-p的长度,即主串中匹配到的开始位置;
  6. 当主串s中所有字符均已匹配完还没有匹配成功,则匹配失败,返回-1。

其中,next数组是KMP算法的关键。next数组记录的是针对每个字符,其之前的字符中最大前后缀匹配长度的值,它决定了在匹配过程中,模式串p中已匹配部分所形成的“状态机”从哪个位置开始继续匹配。next数组可通过类似动态规划的方式进行预处理。

C++实现

在C++中实现KMP算法,我们需要定义一个函数KMP(const char s, const char p),其中s是主串,p是模式串。KMP函数返回的是模式串在主串中匹配到的开始位置。下面是完整代码:

#include <iostream>
#include <cstring>

using namespace std;

void getNext(const char* p, int* next) {
    int i = 0;
    next[0] = 0;
    for (int j = 1; j < strlen(p); j++) { // 遍历模式串p
        while (i > 0 && p[i] != p[j]) {
            i = next[i - 1];
        }
        if (p[i] == p[j]) {
            i++;
        }
        next[j] = i;
    }
}

int KMP(const char* s, const char* p) {
    int i = 0, j = 0;
    int next[strlen(p)];
    getNext(p, next);
    while (i < strlen(s) && j < strlen(p)) {
        if (j == 0 || s[i] == p[j]) {
            i++;
            j++;
        }
        else {
            j = next[j - 1];
        }
    }
    if (j == strlen(p)) {
        return i - j;
    }
    else {
        return -1;
    }
}

int main() {
    const char* s = "ABCABE";
    const char* p = "ABE";
    int pos = KMP(s, p);
    if (pos != -1) {
        cout << "在主串中匹配到模式串的位置为:" << pos << endl;
    }
    else {
        cout << "匹配失败!" << endl;
    }
    return 0;
}

上面代码中的getNext函数用于预处理next数组,KMP函数用于匹配字符串,其实现方式即上文所述的KMP算法流程。

下面是两个实例说明,其中s是主串,p是模式串,pos表示p在s中的开始匹配位置:

  • s = "ABCABE", p = "ABE" => pos = 3
  • s = "AABAAAB", p = "AAA" => pos = 2

总结

本文详细讲解了如何使用C++实现KMP算法。在KMP算法的实现过程中,需要定义KMP函数和getNext函数,需要注意每个函数的作用和实现细节。在实际使用KMP算法时,我们只需要调用KMP函数即可。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c++ 实现KMP算法 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C语言实现动态顺序表的实现代码

    让我来为大家详细讲解一下如何使用C语言实现动态顺序表的实现代码。 1. 动态顺序表的概述 动态顺序表是一种线性表,它基于数组实现。动态顺序表可以自动扩充或缩小其容量以存储数据。动态顺序表中元素的位置是按照它们在数组中的位置来确定的。它们在内存中是连续存储的,因此它们可以通过下标快速访问。 2. 动态顺序表的实现 我们使用C语言的方法来实现动态顺序表。首先,我…

    C 2023年5月23日
    00
  • c语言main函数使用及其参数介绍

    C语言main函数使用及其参数介绍 在C语言程序中,主函数(main函数)是程序的入口,它负责整个程序的执行。main函数的形式如下: int main(int argc, char *argv[]) { //程序语句 return 0; } main函数包括三部分,分别是函数头、函数体和返回值。下面我们对这三部分进行详细介绍。 一、函数头 main函数的函…

    C 2023年5月23日
    00
  • ubuntu系统vscodeC++编译环境配置与使用方式

    下面为你详细讲解“ubuntu系统vscodeC++编译环境配置与使用方式”的完整攻略。 一、安装和配置C++编译环境 1. 安装GCC和G++编译器 在终端执行以下命令来安装GCC和G++编译器: sudo apt install build-essential 2. 安装CMake 在终端执行以下命令来安装CMake: sudo apt install …

    C 2023年5月23日
    00
  • Visual Studio Code配置C、C++环境并编写运行的方法

    接下来我将为您提供Visual Studio Code配置C、C++环境并编写运行的方法的完整攻略。 Visual Studio Code配置C、C++环境并编写运行的方法 1. 安装Visual Studio Code 首先,我们需要安装Visual Studio Code,推荐从官网上下载最新版本。 2. 安装C、C++编译器 Windows环境中,推荐…

    C 2023年5月23日
    00
  • Linux应用调试使用gdb和gdbserver命令详解

    Linux应用调试使用gdb和gdbserver命令详解 在Linux系统中,调试一个应用程序是非常必要的,它可以帮助我们找到代码中的bug或者优化代码的性能。本文将详细讲解在Linux系统中如何使用gdb和gdbserver命令来调试一个应用程序,并提供两个示例。 安装gdb和gdbserver 在开始之前,我们需要安装gdb和gdbserver。在Ubu…

    C 2023年5月23日
    00
  • C++实现评教管理系统

    下面我将详细讲解C++ 实现评教管理系统的完整攻略。 1. 确定需求 在开始编写代码之前,我们需要明确需求。在该项目中,我们需要实现一个评教管理系统,包含学生登录、教师登录、评教功能等。 2. 设计数据库 在设计数据库时,我们需要确定数据库的表结构和字段,其中包括学生表、教师表和评教表。例如: 学生表: 字段 数据类型 描述 id int 学号 name v…

    C 2023年5月30日
    00
  • 浅谈Python 中的复数问题

    浅谈Python 中的复数问题 什么是复数 在数学中,负数的出现,让数轴不再只有正方向,还有负方向。同样的,对于一些无法用实数描述的概念或者物理量(例如电阻、电容、力等),我们也需要在数轴的虚数方向上寻找答案。 虚数定义为 $\sqrt{-1}$ ,通常用字母 i 来表示。复数是实数与虚数的和,形如 $a+bi$ 的形式。 Python 中的复数 在 Pyt…

    C 2023年5月23日
    00
  • ACProtect Professional 1.3C 主程序脱壳(1)(图)

    ACProtect Professional 1.3C 主程序脱壳攻略 1. 准备环境 系统环境:Windows操作系统(建议Windows 7以上) 调试器:OllyDbg、x64dbg或者IDA Pro HEX编辑器:WinHex等工具 脱壳工具:ACProtect Unpacker等 2. 破解过程 2.1 加载目标程序并分析 将ACProtect P…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部