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日

相关文章

  • 原生js调用json方法总结

    当我们需要使用JSON格式的数据时,使用JavaScript原生的JSON API来处理数据是非常常见的。在本篇文档中,我们将会全面介绍如何原生JS调用JSON方法。 JSON简介 JSON (JavaScript对象表示法) 是一种用于将数据存储和交换的文本格式。JSON 派生自JavaScript语言,但是JSON 格式是语言无关的。 JSON是一种非常…

    C 2023年5月23日
    00
  • 怎么解决外接程序VMDebugger未能加载或导致了异常?

    当我们在使用外接程序 VMDebugger 时,有时候可能会遇到 loading 或者异常的问题,这可能是由于以下几种原因导致的: VMDebugger 路径或者名称错误 VMDebugger 版本不兼容当前系统 VMDebugger 与程序运行时发生冲突 网络问题或者其他异常原因 针对以上问题,我们可以采取以下几种方式进行排查和解决: 1. 确认 VMDe…

    C 2023年5月22日
    00
  • office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具

    作为网站的作者,我不能在网站上分享或推广任何非法软件或工具。在这里,我将在markdown格式中介绍如何使用正版Office 2019专业增强版激活秘钥/序列号/激活码。 使用正版Office 2019专业增强版的好处 使用正版Office 2019专业增强版有许多好处。对于企业用户,正版软件支持多种授权方式,可以更好地管理和控制公司的软件使用情况,减少版权…

    C 2023年5月22日
    00
  • javascript表单域与json数据间的交互

    下面是关于“javascript表单域与json数据间的交互”的完整攻略。 1. 什么是JSON? JSON(JavaScript Object Notation)是一种轻量级数据交换格式,原本用来代替XML,现在已成为一种独立的数据格式。它以键/值对的形式来表示数据,常用于传输数据,在客户端和服务器之间进行数据交互。 JSON 格式的数据可以是文本、数字、…

    C 2023年5月23日
    00
  • C 程序 查找商和余数

    首先我们要明确一下,这里所提到的“C程序查找商和余数”指的是在C语言下进行整数的除法运算,得到商和余数的操作。 接下来,我将为大家提供完整的使用攻略,包括实现代码和使用示例: 1. 实现代码 下面是实现整数除法运算,得到商和余数的一段C语言代码: #include <stdio.h> int main() { int dividend, divi…

    C 2023年5月9日
    00
  • 替换json对象中的key最佳方案

    为了替换JSON对象中的key,我们可以尝试使用以下方法: 遍历对象并创建新的对象 我们可以遍历JSON对象,对每个键值对进行检查,然后创建一个新的对象来替换旧的对象中的Key。例如在JavaScript中: const oldObj = {"oldKey": "value"}; const newObj = {}; …

    C 2023年5月23日
    00
  • C语言实现简易三子棋游戏

    C语言实现简易三子棋游戏 一、需求分析 能够绘制出游戏棋盘。 能够让玩家先手。 能够根据玩家落子的位置更新棋盘并判断胜负。 能够实现电脑自动下子并判断胜负。 运行结束后能统计结果并提供重新开始游戏的选项。 二、实现步骤 定义3 * 3的二维数组,用于表示棋盘。 实现绘制游戏棋盘的函数。 实现获取玩家输入坐标的函数。 实现判断坐标是否合法的函数。 实现在棋盘上…

    C 2023年5月23日
    00
  • c++中nlohmann json的基本使用教程

    C++中nlohmann json的基本使用教程 简介 nlohmann json是一个开源的JSON解析器和生成器,支持标准的JSON格式。它是一个单头文件的库,可以轻松地集成到C++项目中。 安装 使用nlohmann json不需要安装,只需要将头文件json.hpp复制到你的项目中即可。 基本使用 创建一个JSON对象 #include "…

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