C语言kmp算法简单示例和实现原理探究

C语言KMP算法简单示例和实现原理探究

概述

KMP算法是一种字符串匹配算法,它能在O(n+m)的时间复杂度内匹配文本串和模式串。与简单的暴力匹配算法相比,它的时间复杂度更低。

实现原理

暴力匹配算法

在了解KMP算法之前,我们先来看一下暴力匹配算法,这是最简单的字符串匹配算法。

暴力匹配算法的实现原理是:假设文本串为T,模式串为P,从T的第一个字符开始,依次比较T和P的每个字符,如果相同,则接着比较下一个字符,如果不同,则从下一个字符重新开始匹配,直到将整个模式串匹配完为止。

KMP算法

KMP算法是一种比暴力匹配算法更高效的字符串匹配算法。它的核心思想是:当出现不匹配时,尽可能地利用已经匹配过的部分,减少模式串和文本串比较的次数。

计算最长公共前缀和最长公共后缀

KMP算法的第一步是计算出模式串的“最长公共前缀”和“最长公共后缀”。

最长公共前缀指的是,以模式串开头的那部分子串中,既是前缀又是后缀的最长子串。例如,模式串“abab”的最长公共前缀是“ab”。

最长公共后缀指的是,以模式串结尾的那部分子串中,既是前缀又是后缀的最长子串。例如,模式串“abab”的最长公共后缀是“ab”。

计算最长公共前缀和最长公共后缀的方法是,以模式串中每个字符为结尾,找到它前面的子串中既是前缀又是后缀的最大长度。此处使用一个next数组来存储最长公共前缀和最长公共后缀的值。

KMP算法实现流程

有了最长公共前缀和最长公共后缀的值之后,就可以开始实现KMP算法了。KMP算法的实现流程如下:

  • 从文本串T的第一个字符开始匹配模式串P的第一个字符。
  • 如果两个字符相等,则继续比较下一个字符。
  • 如果两个字符不相等,则根据next数组移动模式串。
  • 重复步骤2和步骤3,直到找到匹配或者文本串匹配完为止。

KMP算法的关键在于如何根据next数组移动模式串。

假设文本串T的当前位置是i,模式串P的当前位置是j,出现不匹配时,模式串需要移动的距离是k = j - next[j]。移动模式串的时候,需要将模式串的前k个字符跳过,从第k+1个字符开始继续比较。

关于next数组的计算

next数组的第一个元素next[0]必须是-1,表示移动模式串到第一个字符之前。next数组的其他元素计算方法如下:

  • next[0] = -1
  • 如果模式串的前j个字符(不包括第j个字符)与模式串的前k个字符(不包括第k个字符)匹配,则next[j] = k。
  • 如果模式串的前j个字符(不包括第j个字符)与模式串前缀的一个子串匹配,则递归地寻找匹配的最大长度,即next[k]。

示例

示例1

有一个文本串T:“ABCDABD”,和一个模式串P:“ABD”。

模式串P和文本串T的匹配过程如下:

  1. T[1]和P[1]相等,继续比较下一个字符;
  2. T[2]和P[2]相等,继续比较下一个字符;
  3. T[3]和P[3]不相等,根据next数组将P向右移动2个字符(即跳过AB),改成在T[3]和P[1]比较。
  4. T[3]和P[1]不相等,继续向右移动模式串,变成在T[3]和P[0]比较(即P前面加一个未匹配的字符)。
  5. T[3]和P[0]不相等,因为next[0]=-1,所以将模式串P向右移动1个字符;
  6. 继续比较T[3]和P[1],相等,继续比较下一个字符;
  7. T[4]和P[2]相等,继续比较下一个字符;
  8. T[5]和P[3]相等,完成匹配。

示例2

有一个文本串T:“ACABAABAACACAADABAA”,和一个模式串P:“AABAAC”。

模式串P和文本串T的匹配过程如下:

  1. T[1]和P[1]相等,继续比较下一个字符;
  2. T[2]和P[2]相等,继续比较下一个字符;
  3. T[3]和P[3]不相等,根据next数组将P向右移动3个字符(即跳过AAB),改成在T[3]和P[1]比较。
  4. T[3]和P[1]不相等,继续向右移动模式串,变成在T[3]和P[0]比较(即P前面加一个未匹配的字符)。
  5. T[3]和P[0]不相等,因为next[0]=-1,所以将模式串P向右移动1个字符;
  6. 继续比较T[3]和P[1],相等,继续比较下一个字符;
  7. T[4]和P[2]相等,继续比较下一个字符;
  8. T[5]和P[3]相等,继续比较下一个字符;
  9. T[6]和P[4]相等,继续比较下一个字符;
  10. T[7]和P[5]相等,完成匹配。

总结

KMP算法是一种高效的字符串匹配算法。通过计算模式串的最长公共前缀和最长公共后缀,可以减少模式串和文本串比较的次数,提高匹配效率。在实际开发中,可以使用KMP算法来实现字符串匹配功能,例如搜索引擎中的关键字查询等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言kmp算法简单示例和实现原理探究 - Python技术站

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

相关文章

  • 红与黑

    有一个矩形房间,覆盖正方形瓷砖。每块瓷砖涂成了红色或黑色。一名男子站在黑色的瓷砖上,由此出发,可以移到四个相邻瓷砖之一,但他不能移动到红砖上,只能移动到黑砖上。编写一个程序,计算他通过重复上述移动所能经过的黑砖数(一开始站立的黑砖也要算)。 输入 开头行包含两个正整数W和H,W和H分别表示矩形房间的列数和行数,且都不超过20.每个数据集有H行,其中每行包含W…

    C 2023年4月24日
    00
  • Java面试题冲刺第一天–基础篇1

    下面我将详细讲解“Java面试题冲刺第一天–基础篇1”的完整攻略。 一、需求分析 本篇攻略是针对Java初学者、准备面试的人群而编写的,旨在帮助大家复习Java基础知识,从而在面试中表现更加出色。 该篇攻略包含以下几个方面的内容: Java基础知识概述 Java数据类型 Java运算符与表达式 Java流程控制语句 Java数组 通过学习和掌握这些内容,可…

    C 2023年5月23日
    00
  • 海康存储C4000ECO 1T怎么样? 海康存储C4000ECO 1T固态硬盘测评

    海康存储C4000ECO 1T固态硬盘测评 概述 海康存储C4000ECO 1T是一款固态硬盘,采用SATA III接口,配备1TB的存储容量。本文对该固态硬盘进行了细致的评测和测试,下面详细介绍该固态硬盘的性能表现。 性能测试 读写速度测试 我们使用CrystalDiskMark软件进行了读写速度测试,测试结果如下: ——————-…

    C 2023年5月23日
    00
  • Vue.js实现的计算器功能完整示例

    下面我会详细讲解Vue.js实现的计算器功能完整示例的攻略。 准备工作 在开始实现计算器之前,需要在HTML文件中引入Vue.js和一个CSS文件。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Vue C…

    C 2023年5月22日
    00
  • Java爬虫 信息抓取的实现

    Java爬虫可以通过模拟浏览器的行为,自动化地访问网页并抓取所需信息,主要分为以下几个步骤: 1. 简述Web爬虫的基本工作流程 1.1 网页访问 要抓取的信息一般都在网页中,因此第一步是访问目标网站。由于Java爬虫需要模拟浏览器的行为,因此一般使用java.net.HttpURLConnection或org.apache.http.client.Http…

    C 2023年5月23日
    00
  • 深入解析C++程序中激发事件和COM中的事件处理

    深入解析 C++ 程序中激发事件和 COM 中的事件处理的攻略如下: 1. 什么是事件 事件是指在程序执行期间发生的动作或者状态变化,通常情况下需要在特定条件下触发。事件处理程序是由程序编写人员编写的一段代码,在事件触发时被执行。在 C++ 程序和 COM 中,都存在着事件的概念,因此需要掌握它们的事件处理方式。 2. C++ 中的事件处理 C++ 中的事件…

    C 2023年5月23日
    00
  • ubuntu 下编译C++代码出现的问题解决

    针对Ubuntu下编译C++代码出现的问题进行解决需要考虑以下几个步骤: 1.更新apt-get,确保系统软件包是最新的 sudo apt-get update sudo apt-get upgrade 2.安装C++编译器和构建工具 sudo apt-get install build-essential sudo apt-get install g++ …

    C 2023年5月23日
    00
  • 浅析c#中如何在form的webbrowser控件中获得鼠标坐标

    下面是详细讲解“浅析C#中如何在Form的WebBrowser控件中获得鼠标坐标”的完整攻略。 什么是WebBrowser控件 WebBrowser控件是Windows Forms中的一种控件,用于在Form窗体中嵌入一个Web浏览器。WebBrowser控件是一个包装了Internet Explorer浏览器的 ActiveX 控件,支持网页浏览、脚本执行…

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