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

article/2025/10/4 0:15:40

目录

文章目录

前言

一、BF算法

二、KMP算法

1.算法介绍

2.算法思路

 3.整体代码实现

总结


前言

字符串匹配算法又称模式匹配算法,该算法的目的是为了子串从主串中寻找是否有与其匹配的部分,

其可分为BF暴力检索、RK哈希检索、KMP、BM等等,本文仅介绍BF算法和KMP算法的实现,前者的时间复杂度是O(mn),后者的时间复杂度是O(m+n),本次文章就是对这两者的核心思路进行总结分析,以加强记忆。


一、BF算法

算法要求:假设有两个字符串,主串S和子串X,通过BF算法的逐步匹配,找到与子串匹配的主串部分,并返回第一次出现的下标。

算法思路如下:

 代码实现如下(C语言):

#include<stdio.h>
#include<assert.h>
#include<string.h>int BF(char* str, char* sub)//str代表主串,sub代表子串
{assert(str&&sub);//断言if (str == NULL || sub == NULL)//串为空值时直接返回-1{return -1;}int i = 0;//遍历主串int j = 0;//遍历子串int lenstr = strlen(str);//求出主串的长度int lensub = strlen(sub);//求出子串的长度while ((i < lenstr) && (j < lensub))//当子串遍历结束或主串遍历结束时,跳出循环{if (str[i] == sub[j])//匹配成功{i++;j++;}else//匹配失败{i = i - j + 1;j = 0;}}if (j >= lensub)//如果是因为子串遍历结束而跳出循环,说明匹配成功,返回下标{return i - j;}else//匹配失败,返回-1return -1;
}
int main()
{printf("%d\n", BF("ababcabcdabcde", "abcd"));//匹配成功,预期返回下标5printf("%d\n", BF("ababcabcdabcde", "abcds"));//匹配失败,返回-1printf("%d\n", BF("ababcabcdabcde", "ab"));//匹配成功,返回下标0return 0;
}

 BF算法缺点:有大量匹配无效,效率低。

二、KMP算法

1.算法介绍

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特--莫里斯--普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。

2.算法思路

①next数组的求解:

例:有一个字符串ababcabc,求其对应的next数组。

解:第一个字符对应的next数组值为-1,第二个字符对应的next数组值为0,从第三个字符开始,判断第一个字符和第(n-1)个字符中是否有匹配的

数学分析:

假设next[i]=k,可推出p[0]...p[k-1]=p[x]...p[i-1],既k-1-0=i-1-x,得x=i-k

p[0]...p[k-1]=p[i-k]...p[i-1]

若能证得p[i]==p[k],则可求得next[i+1]=k+1

若p[i]!=p[k],next[i+1]=??

举个例子:


 代码分析:

void GetNext(char* sub, int* next, int lensub)/*sub代表子串;next是外部开辟的动态内存数组;lensub是子串长度*/
{next[0] = -1;next[1] = 0;int i = 2;//当前i下标int k = 0;//前一项的kwhile(i < lensub){if (k == -1 || sub[i - 1] == sub[k])//k回退到-1或前一项sub[i-1]==sub[k]{next[i] = k + 1;i++;k++;}else{k = next[k];//if条件不满足时则需将k回退到-1下标}}
}

附加知识: next数组的优化(nextval)

同样以例子来讲:

图中所示,当i=5时匹配失败,若按照next数组回退的话,到i=4时,依旧是a,匹配失败还得回退,每次回退都是相同的字符,这些回退无疑是无效的。而nextval数组就是对这一现象的优化。

 3.整体代码实现

#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
void GetNext(char* sub, int* next, int lensub)/*sub代表子串;next是外部开辟的动态内存数组;lensub是子串长度*/
{next[0] = -1;next[1] = 0;int i = 2;//当前i下标int k = 0;//前一项的kwhile(i < lensub){if (k == -1 || sub[i - 1] == sub[k])//k回退到-1或前一项sub[i-1]==sub[k]{next[i] = k + 1;i++;k++;}else{k = next[k];//if条件不满足时则需将k回退到-1下标}}
}int KMP(char* str, char* sub, int pos)/*str:代表主串;sub:代表子串;pos:代表从主串的pos位置开始找*/
{assert(str&&sub);//断言if (str == NULL || sub == NULL)//字符串为空直接返回-1return -1;int lenstr = strlen(str);//求主串长度int lensub = strlen(sub);//求子串长度if (pos < 0 || pos >= lenstr)//pos位置不合法直接返回-1return -1;int *next = (int*)malloc(sizeof(int)*lensub);//开辟动态内存给next数组存放数据assert(next);GetNext(sub, next,lensub);//求出next数组int i = pos;//遍历主串int j = 0;//遍历子串while (i < lenstr&&j < lensub){if (j == -1 || str[i] == sub[j]){i++;j++;}else{j = next[j];}}free(next);next = NULL;if (j >= lensub){return i - j;}return -1;
}int main()
{printf("%d\n", KMP("ababcabcdabcde", "abcd", 0));//预期返回5printf("%d\n", KMP("ababcabcdabcde", "abcdf", 0));//预期返回-1printf("%d\n", KMP("ababcabcdabcde", "ab", 0));//预期返回0return 0;
}

总结

以上就是今天要讲的内容,本文介绍了关于字符串匹配的BF算法和KMP算法,通过比特大博哥的视频学习,对算法思路与实现代码进行理解和分析,简单学习记录。欢迎大家探讨指正!


http://chatgpt.dhexx.cn/article/AfnuTIpX.shtml

相关文章

shell字符串匹配

一、简介 Bash Shell提供了很多字符串和文件处理的命令。如awk、expr、grep、sed等命令&#xff0c;还有文件的排序、合并和分割等一系列的操作命令。grep、sed和awk内容比较多故单独列出&#xff0c;本文只涉及字符串的处理和部分文本处理命令。 二、字符串处理 1、expr命令…

golang字符串匹配算法

简介 字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串&#xff08;称为模式串&#xff09;。在 Golang 中&#xff0c;可以使用最常见的字符串匹配算法之一&#xff1a;Knuth-Morris-Pratt&#xff08;KMP&#xff09;算法&#xff0c;它的时间复杂度为 O(nm…

【数据结构】字符串匹配(暴力匹配)

原理解析&#xff1a; 字符串匹配方法&#xff0c;创建两个字符串结构&#xff0c;主 串和子串比较。 主串字符 a 和 子串字符 c 不匹配&#xff0c;主串的指针向下移动&#xff0c;移动到上一次开始比较的下一个位置。 子串指向开始的位置。 主串字符 b 和 子串字符 c 不匹配…

字符串匹配算法比较

字符串匹配&#xff08;string match)是在实际工程中经常会碰到的问题&#xff0c;通常其输入是原字符串(String)和子串&#xff08;又称模式&#xff0c;Pattern)组成&#xff0c;输出为子串在原字符串中的首次出现的位置。通常精确的字符串搜索算法包括暴力搜索(Brute force)…

子串查找(字符串匹配)

子串查询 首先&#xff0c;我们来定义两个概念&#xff0c;主串和模式串。我们在字符串 A 中查找字符串 B&#xff0c;则 A 就是主串&#xff0c;B 就是模式串。我们把主串的长度记为 n&#xff0c;模式串长度记为 m。由于是在主串中查找模式串&#xff0c;因此&#xff0c;主串…

字符串匹配算法综述

字符串匹配算法综述 字符串匹配算法综述&#xff1a;BF、RK、KMP、BM、Sunday 字符串匹配算法&#xff0c;是在实际工程中经常遇到的问题&#xff0c;也是各大公司笔试面试的常考题目。此算法通常输入为原字符串&#xff08;string&#xff09;和子串&#xff08;pattern&…

字符串匹配算法详解

希望看到文章的你们&#xff0c;能够在今年的研究生考试中超常发挥。 愿你们都能考上自己心仪的学校&#xff0c;为你们的备考生涯划上一个完美的句号。做为你们的师兄有几句话想对你们说&#xff0c;希望这些话能对你们有一些帮助。 马上就要考试了&#xff0c;不要再继续啃难…

字符串匹配算法

字符串匹配就是在主串A中查找模式串B&#xff0c;例如在主串abababc中查找模式串abc是否存在&#xff0c;记主串A的长度为n&#xff0c;模式串B的长度为m&#xff0c;n>m。 BF算法 BF(Brute Force)算法&#xff0c;又叫暴力匹配算法或者朴素匹配算法&#xff0c;思路很简单…

字符串(字符串匹配)

一、字符串匹配问题、基础 1、假设文本是一个长度为n的数组T&#xff0c;而模式是长度为m的数组P&#xff0c;我们希望在文本T中寻找模式P 如果P出现在T中的第s个位置&#xff0c;那么我们称其有效偏移为s&#xff0c;在其他不匹配的位置称为无效偏移 2、如果字符串w是字符串…

字符串匹配

字符串匹配 1.朴素的串匹配算法(暴力解法) 1.1 分析 设t是目标串&#xff08;母串&#xff09;&#xff0c;p是模式串&#xff08;待匹配串&#xff09;&#xff0c;i , j 分别指向 模式串 和 目标串&#xff0c;m、n分别是模式串p和目标串t的长度。 从目标串的第0个字符&am…

Photoshop怎么给图片添加简介信息或者版权信息

转自&#xff1a;Photoshop怎么给摄影图片添加作者名字版权等信息? 有时我们点开一张图片的详细信息中可能可以看到各种属性信息&#xff0c;比如作者&#xff0c;时间&#xff0c;关键字&#xff0c;图片信息描述等属性&#xff0c;但是我们自己的拍摄的或者从别的地方获取的…

2022年中国版权保护中心计算机软件著作权登记最全申请步骤流程

一、前言二、实名认证1. 用户注册2. 实名认证 三、办理步骤1. 办理流程2. 填写申请表3. 提交申请文件4. 登记机构受理申请5. 审查6. 获得登记证书 四、登记申请所需文件1. 软件著作权登记申请表2. 软件&#xff08;程序、文档&#xff09;的鉴别材料3. 有关证明文件 五、申请表…

IDEA设置版权信息

File→Settings或者CtrlS快捷键。 Editor下面有个Copyright→Copyright Profiles 点击加号&#xff0c;然后输入名称。 然后修改成自己的信息&#xff1a; 其中第一个年份是本文件新建日期&#xff0c;后面的是最后一次修改年份。 中文版本&#xff1a; 版权所有(c) Jack魏 …

版权和版本信息

版权和版本信息的主要内容有&#xff1a; &#xff08;1&#xff09;版权信息&#xff1b; &#xff08;2&#xff09;文件名称、简要描述、创建日期和作者&#xff1b; &#xff08;3&#xff09;当前版本信息和说明&#xff1b; &#xff08;4&#xff09;历史版本信息和…

版权和商标权有什么关系?版权和商标的区别在哪里?

版权和商标权存在着一定的关系&#xff0c;版权和商标又有着很多区别&#xff0c;具体的关系和区别是怎样的&#xff0c;大家都知道吗&#xff1f;今天企多多就带大家来了解&#xff01; 版权和商标权的关系 版权和商标权的关系主要有以下三点&#xff1a; 1、关联性&#xf…

版权 | 收藏!哪些作品可以登记版权?

创业创新中&#xff0c;无论是公司LOGO还是IP形象或者产品手册&#xff0c;都凝结着无数的心血。当下互联网和科技的发展&#xff0c;让抄袭变得前所未有的容易&#xff0c;尤其在美术作品、文字作品和影视作品领域。如何有效地保护自己的智力成果呢&#xff1f;先从了解这些开…

Pyinstaller加入版本和版权信息

目录 参考链接 前言 一. 获取版本信息 1. 拖过来个有版本和版权信息的exe文件 2. 放置一个txt文件 我们接着放置一个txt文件叫file_version_info.txt。这名字不能改&#xff0c;Pyinstaller自动就把版权信息放在这里。 3.开始获取 二. 修改 三. 打包 参考链接 pyinsta…

版权信息的生成方法

网页底部添加网站的版权信息&#xff0c;将版权信息封装到JavaBean中&#xff0c;可重复利用 新建JavaBean类 public class StringUtil3 {private String copyrightStr"xxxxxxxxxxx xxxxxxxxxxxxx--xxxxxxxxxxxxxxxxxxxx-xxx";public String getCopyrightStr() {ret…

C++虚函数表

一、背景知识&#xff08;一些基本概念&#xff09; 虚函数&#xff08;Virtual Function&#xff09;&#xff1a;在基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数。 纯虚函数&#xff08;Pure Virtual Function&#xff09;&#xff1a;基类中没有实现体…

虚函数和虚函数表

多态是由虚函数实现的&#xff0c;而虚函数主要是通过虚函数表&#xff08;V-Table&#xff09;来实现的。 如果一个类中包含虚函数&#xff08;virtual修饰的函数&#xff09;&#xff0c;那么这个类就会包含一张虚函数表&#xff0c;虚函数表存储的每一项是一个虚函数的地址…