初识kmp算法(呕心沥血之文----看视频+总结)

大一菜鸟,即将大二,依旧菜鸟一只QAQ

最近在中国大学慕课上看数据结构的课程,我看的是西安邮电大学的数据结构与算法课,kmp算法出现在“串”那一章节

具体内容我就不细讲了,大家可以去看一下。老师讲得还是很明白的。

  • next数组的实现

注意:网上的课程中默认字符串的下标从1开始

实现思路:

初识kmp算法(呕心沥血之文----看视频+总结)_第1张图片

比如j=4时next[4]=2,即下次比较时从第二个字符开始比较(下标从1开始),第一个0指下次比较时从第一个字符开始

代码实现:(注意下标从1开始)

int main() {
    char s1[maxn],s2[maxn];//s1是文本串,s2是模式串
    int next[maxn];
    scanf("%s",s2+1);//从1开始读或者写成cin>>s2+1;
    int i,j=1,k=0,len=strlen(s2+1);
    next[1]=0;
    while(j

以ababcabaababb为例,输出如下:

  • kmp算法的实现:

思路:

初识kmp算法(呕心沥血之文----看视频+总结)_第2张图片

实现代码:


int main() {
    char s1[maxn],s2[maxn];//s1是文本串,s2是模式串
    int next[maxn];
    scanf("%s%s",s1+1,s2+1);
    int i=1,j=1,len1=strlen(s1+1),len2=strlen(s2+1);//i指向文本串,j指向模式串,从文本串
                                                //的第i位开始查找
    while(i<=len1&&j<=len2)
    {
        if(j==0||s1[i]==s2[j])
        {
            i++;
            j++;
        }
        else j=next[j];
    }
    if(j>len2) cout<
  • 实现kmp算法的完整代码:

#include 
#include 
#include 
#include 
#include 
#define maxn 1000000
using namespace std;
int main() {
    char s1[maxn],s2[maxn];//s1是文本串,s2是模式串
    int next[maxn];
    scanf("%s%s",s1+1,s2+1);
    int i=1,j=1,k=0,len1=strlen(s1+1),len2=strlen(s2+1);//i指向文本串,j指向模式串
    next[1]=0;
    while(jlen2) cout<

输出结果:

ababcabaababb
abaa
0 1 1 2 
6

但是,思考在计算next数组时,如果s2=aaaaab,s2对应的next数组为0 1 2 3 4 5

如果在比较第4位时不同需要进行如图操作:

初识kmp算法(呕心沥血之文----看视频+总结)_第3张图片

实际上我们知道,模式串第四位之前的字母也都是a,所以在按之前的操作执行的话肯定都是不等的,最后还是重新要从模式串的第一位比较,同时指向文本串的i右移一位,所以这个时候直接执行“从模式串的第一位比较,同时指向文本串的i右移一位”这个操作即可,如下图:

初识kmp算法(呕心沥血之文----看视频+总结)_第4张图片

黑色框内的步骤无需执行,直接执行橙色圈内的操作即可,所以需要对之前的next数组,进行优化,我们称它为nextval数组,用nextval数组来代替next数组

  • nextval数组的实现

初识kmp算法(呕心沥血之文----看视频+总结)_第5张图片

实现代码:

#include 
#include 
using namespace std;
#define maxn 100000//如果数组定义在main内,不能开太大
int main()
{
    char s1[maxn],s2[maxn];//s1文本串,s2模式串
    scanf("%s",s2+1);
    int i,j,k,len1=strlen(s1+1),len2=strlen(s2+1);
    int next[maxn],nextval[maxn];
    next[1]=0;
    j=1,k=0;
    while(j
aaaaab
0 1 2 3 4 5 
0 0 0 0 0 5
  • 优化后的kmp算法的完整代码为:(终极版)

#include 
#include 
using namespace std;
#define maxn 100000//如果数组定义在main内,不能开太大
int main()
{
    char s1[maxn],s2[maxn];//s1文本串,s2模式串
    scanf("%s%s",s1+1,s2+1);
    int i,j,k,len1=strlen(s1+1),len2=strlen(s2+1);
    int next[maxn],nextval[maxn];
    next[1]=0;
    j=1,k=0;
    while(jlen2) cout<

输出样例:

ababcabaababb
abaa
6
aaaaab
ab
5

最后一个代码才是完整的kmp代码,至此,查找(匹配)子串,并返回相匹配时第一个字母出现的位置的知识点就都总结完了

还是不懂的盆友可以看我在博客开头推荐的视频或者和百度哦~我也只是微微懂一些罢了哈哈哈

欢迎交流讨论,非诚勿扰哦~邮箱:[email protected]

你可能感兴趣的:(算法基础知识储备,kmp)