C语言实现字符串匹配KMP算法

yizhihongxing

C语言实现字符串匹配KMP算法

什么是KMP算法

字符串匹配是计算机科学中的一个基本问题,给定两个文本串A和B,其中A称为主串,B称为模式串,现在要查找B在A中第一次出现的位置,这就是字符串匹配的问题。

KMP算法(Knuth-Morris-Pratt算法)是一种字符串匹配算法,它利用了字符串的局部匹配特性来提升匹配效率。与暴力匹配算法相比,KMP算法的时间复杂度为O(n+m),其中n是主串的长度,m是模式串的长度,相比之下,暴力匹配算法的时间复杂度为O(n*m)。

KMP算法的实现过程

KMP算法实现的核心是构造模式串的next数组,next数组中存储的是模式串中所有前缀子串中最长的相等前缀后缀的长度。

具体实现过程如下:

  1. 构造next数组

首先需要预处理模式串的next数组,如果next[i] = j,则表示模式串的前i个字符中,最长的相等前缀后缀的长度为j。

构造next数组的过程分为三步:

(1)初始化next数组为0

(2)通过遍历模式串生成next数组,找到当前位置前面最长相等前后缀的长度

(3)当找到当前位置的最长相等前后缀时,更新next数组

  1. 匹配主串和模式串

利用已经构造好的next数组,进行主串和模式串的匹配

如果模式串和主串的字符匹配成功,模式串和主串的索引值都加1;如果匹配不成功,则主串的索引值不变,模式串的索引值变为next[j]。

最后如果匹配成功,返回主串中匹配的起始位置,如果匹配失败,返回-1。

KMP算法的C语言实现

以下是KMP算法在C语言中的实现,包含匹配函数和构造next数组的函数:

#include <stdio.h>
#include <string.h>

void getNext(char *pattern, int *next) {
    int i = 0, j = -1;
    next[0] = -1;
    while (i < strlen(pattern)) {
        if (j == -1 || pattern[i] == pattern[j]) {
            i++;
            j++;
            next[i] = j;
        } else {
            j = next[j];
        }
    }
}

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

示例

以下是对上述KMP算法的两条示例说明。

示例1

假设我们要在文本串中查找模式串ABCDABD,文本串为ABCDEFGABCDABCEFG,上述kmp函数的调用过程如下:

kmp("ABCDEFGABCDABCEFG", "ABCDABD");

得到的结果是:

7

表示模式串ABCDABD在文本串中从第7个位置开始出现。

示例2

假设我们要在文本串中查找模式串hello,文本串为hello world,上述kmp函数的调用过程如下:

kmp("hello world", "hello");

得到的结果是:

0

表示模式串hello在文本串中从第0个位置开始出现。

总结

KMP算法是一种高效的字符串匹配算法,在实现过程中需要理解next数组的概念和构造方法,代码实现过程相对较简单,但需要考虑到细节问题,如边界处理,数组下标从0开始等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现字符串匹配KMP算法 - Python技术站

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

相关文章

  • C语言 strftime 格式化显示日期时间的实现

    C语言提供了strftime函数用于将日期时间按照指定格式转换为字符串,下面是使用步骤: 步骤一:头文件引入 #include <time.h> 步骤二:分配时间结构体 struct tm *tm; time_t timep; time(&timep); //获取秒数 tm = localtime(&timep); //转为日期时…

    C 2023年5月22日
    00
  • C语言实现单词小助手

    关于“C语言实现单词小助手”的攻略,我将从以下几个方面进行讲解: 需求分析和功能设计 单词数据的获取和处理 单词查询和输出 代码实现和测试 1. 需求分析和功能设计 首先,我们需要对单词小助手的功能进行分析和设计。可以考虑以下几个功能: 能够从外部文件或数据库中获取单词数据 能够根据用户输入的单词,查询并输出单词的解释和例句 能够进行模糊查询,即用户输入单词…

    C 2023年5月23日
    00
  • 2019年滴滴出行前端工程师面试题(附答案)

    下面是详细讲解“2019年滴滴出行前端工程师面试题(附答案)”的完整攻略。 理解面试题意思 首先,要认真阅读所有面试题目,并理解每个问题的意思。针对每个问题,需要理解问题的背景、要求和解决方案。在阅读问题时,可以结合实际场景或者经验,尝试通过自己的思考,预测和解答面试官可能会继续提问的问题。 例如,题目中的第一个问题:“如何实现一个模块加载器?”,我们可以针…

    C 2023年5月23日
    00
  • win10下定时运行与开机自启动jar包的方法记录

    我来给你详细讲解win10下定时运行与开机自启动jar包的方法。我们可以分为两个部分来讲解,下面将分别进行详细介绍。 一、定时运行jar包的方法记录 1.安装JRE环境 在运行Java程序之前,需要安装Java Runtime Environment(JRE)环境。可以在官网下载安装。 2.运行jar包 运行jar包有多种方法,我们这里介绍一种简单的方法:使…

    C 2023年5月22日
    00
  • C语言求阶乘之和的三种实现方法(先阶乘再累加)

    当我们需要计算n的阶乘之和时,可以采用以下三种方法进行实现: 方法一:单层for循环 在本方法中,我们可以将for循环的条件直接设为i<=n即可,每次循环计算i的阶乘并加到sum中,最后输出sum即可。 示例代码: #include <stdio.h> int main() { int n, sum=0, factorial=1; prin…

    C 2023年5月23日
    00
  • c语言中&的用法示例代码

    下面是关于 C 语言中 & 的用法攻略,针对此问题,我们需要从以下两个方向进行讲解: 变量声明和引用时的 & 符号使用 当我们声明一个变量时,可以使用 & 符号获取该变量的地址。例如: int x = 10; int *p = &x; 上述代码中,我们声明了一个整型变量 x,并将其初始化为 10。然后,我们使用指针变量 p 来…

    C 2023年5月24日
    00
  • C语言实现简单员工工资管理系统

    C语言实现简单员工工资管理系统 简介 本文旨在介绍如何使用C语言实现一个简单的员工工资管理系统。该系统可以用于输入员工基本信息,录入工资数据和计算每个员工的工资。其主要功能模块包括:输入员工基本信息、录入工资数据、计算员工工资、显示员工工资信息。 基本功能 输入员工基本信息:包括员工的姓名、性别、年龄、工龄等信息。 示例代码: “`c struct emp…

    C 2023年5月23日
    00
  • C++11新增的包装器详解

    C++11新增的包装器详解 概述 C++11引入了许多新的特性,其中一个重要的特性是包装器。包装器是指能够包装任意类型的值,并且能够按照指定方式进行数据转换和操作的工具类。C++11中新增加的包装器主要有以下几个: std::shared_ptr: 表示一个共享所有权的指针,即多个指针指向同一个对象,在对象不被使用时自动释放。 std::unique_ptr…

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