KMP算法详解(理论+C语言代码实现)(上)

简介: KMP算法详解(理论+C语言代码实现)

一:KMP算法与BF算法的区别与特点

1.KMP算法和BF算法的定义

1.KMP算法:

  • KMP算法是一种改进的字符串匹配算法
  • KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。
  • 具体实现就是通过一个next数组实现,数组本身包含了模式串的局部匹配信息。
  • KMP算法的时间复杂度O(m+n)

2.BF算法:

BF算法,即暴力(Brute Force)算法,是普通的模式匹配算法,

BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,

若相等,则继续比较S的第二个字符和 T的第二个字符;

若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果。

BF算法是一种暴力算法。

2.KMP算法和BF算法的区别

KMP和BF唯一不一样的地方在于:

KMP算法中的主串的i并不会回退,并且j也不会移动到0号位置

此时主串跟子串匹配失败,

如果是BF算法的话,i会回退到下标1的位置,j会回退到下标0的位置再次进行匹配

如果是KMP算法的话,i不会回退,只有j会回退,我们会感到惊讶,怎么做到的啊?

我们先通过肉眼观察一下,

那么我们如何在主串中找到和子串匹配的一部分串呢?

这里就需要用到next数组了

二:next数组的求解

1.next数组求法(理论):

next数组的作用:

保存子串某个位置匹配失败后回退的位置

定义:

next[j]=k;

如果j下标匹配失败时,那么下次匹配时j回退到下标为k的位置

手求next数组:

而k的值是这样求的:

1:找到匹配成功部分的两个相等的真子串(不包含本身),一个以下标0开始,另一个以下标j-1结尾.

2:不管怎样都有:next[0]=-1;next[1]=0;

next数组也可以从0开始,也就是next[0]=0;

只需把我们上面那种形式所求出的next数组中的值全部加1即可

2.next数组求法(实操):

下面我们演示一下next数组的求法

3.求next数组练习题:

下面是两个例子,大家可以先做一下,巩固巩固,我们还要从这两个例子中再说明一些重要的点

友情提醒:

  • 两个相等的串:第一个串必须从0下标处开始
  • 第二个串必须从j-1下标处结尾
  • next数组的两个相同子串是可以重合的

1.

“ababcabcdabcde”,求next数组

2.

“abcabcabcabcdabcde”,求next数组

3.练习题总结

通过这两个题,我们可以发现:

1.next数组不可能跳着加!!!,所以,如果你求出来的next数组有跳着加的现象,那证明你做错了

2.也就是说next数组满足若next[j]=k,p[j]==p[k],那么next[j+1]=k+1;(p是子串)

相关文章
|
13天前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
25天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
28 3
|
24天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
1月前
|
存储 缓存 算法
如何通过优化算法和代码结构来提升易语言程序的执行效率?
如何通过优化算法和代码结构来提升易语言程序的执行效率?
|
30天前
|
缓存 分布式计算 监控
优化算法和代码需要注意什么
【10月更文挑战第20天】优化算法和代码需要注意什么
18 0
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
35 3
|
算法 C语言
KMP—C语言实现
KMP算法
1641 0
|
14天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
29 6
|
1月前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
39 10
|
27天前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。
下一篇
无影云桌面