Loading

数据结构与算法题型——chapter 1:KMP算法

数据结构与算法题型——chapter 1:串与kmp算法

KMP算法

首先要明确kmp算法中有一个数组,叫做前缀数组,也叫做next数组,每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符,当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大。

在描述kmp算法时为了形象,将提高算法效率的方法说成:不让主串的指针回溯,将模式串“ 滑动 ” 尽可能的距离后,继续进行比较。这里的滑动是加了引号的滑动,实际是指针指向数组下标的更换。

要了解两个概念:“前缀"和"后缀”。 "前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。

数组的求法:

当 j == 1 时,也就是指向模式串中的第一个元素,即第一个元素已经与主串发生失配,那么指向子串的指针不变,指向主串的指针要向后移动一位,以进行比较。则next【 j 】= 0

L(max)是匹配过的子串中最大相等前后缀的长度,next【 j 】= L(max)+ 1,

当匹配过的字串没有最大相等前后缀时,next【 j 】= 1


在这里插入图片描述

就像这一题:

模式串的指针我们默认为 j 。

1、j 指向 a ,a是模式串中的第一个元素,所以为 0

2、j 指向 b ,前面只有 a ,没有最大相等前后缀,所以为 1

3、j 指向 a ,前面匹配过的子串是 ab , 没有最大相等前后缀 ,所以next数组中的数为 1

4、j 指向 b ,前面匹配过的子串是 aba , 最大相等前后缀为 1 ,所以next数组中的数为 2

5、j 指向 a ,前面匹配过的子串是 abab ,最大相等前后缀为 2 ,所以next数组中的数为 3

6、j 指向 b ,前面匹配过的子串是ababa ,最大相等前后缀为 3 ,所以next数组中的数为 4

7、j 指向 a ,前面匹配过的子串是ababab , 最大相等前后缀为 4 ,所以next数组中的数为 5

8、j 指向 a ,前面匹配过的子串是abababa ,最大相等前后缀为 5 ,所以next数组中的数为 6

9、j 指向 b ,前面匹配过的子串是abababaa , 最大相等前后缀为 1 ,所以next数组中的数为 2

所以next【 j 】数组为 0 1 1 2 3 4 5 6 2

到此依靠人脑next数组中数值的判断已经没问题了


接下来就是让计算机知道怎么求解next数组中的值了

也就是编程求得next数组的函数值(也是最难的 呜呜呜呜)

Round10—串_你倒是敲代码鸭.-CSDN博客

先插入一个有些新意和代表性的kmp算法编程题

接下来是关于kmp算法的编程实现:

首先明白next数组是对应子串的,也就是说主串中可能包含多个子串,即子串在主串中多次出现,但是next数组中的值只有一个,因为子串确定,不会因为字串在主串中多次出现而使得next数组中的值发生改变,子串的长度就是next数组的长度😆👏👏👏👏

start+> 会出现表情选项😆😉

#include<bits/stdc++.h>
using namespace std;
#define MAXSTRLEN 255
int main()
{
    char S[MAXSTRLEN + 1];
    char T[MAXSTRLEN + 1];
    cin >> S1 >> S2;
    
    
}

pta错题集

kmp算法中要知道next【i】取值的依据然后才能进行模式匹配

next【i】数组的求解

在这里插入图片描述

8+7+6+5+4+3+2+1+1(空串)

= 37


KMP算法计算next值和nextVal值

KMP算法:

给定一个主串S及一个模式串P,判断模式串是否为主串的子串;若是,返回匹配的第一个元素的位置(序号从1开始),否则返回0;

这里先不写算法,仅仅计算next和nextVal值

那么计算时只用到子串,也就是模式串

这里模式串为:abaabcac

第一步将模式串写上序号,我们这里从1开始(有的从0开始,建议从1开始)

img
然后计算出最大相等前后缀的值,列出从第一个开始的子串,找出相等的前缀和后缀的个数

如果2>看不懂的话,看3>,

2>计算最大相等前后缀的值

img
所以最大相等前后缀的值即maxL值

img
如果这个看不懂的话, 看下面的3>

3>, 如果2>看懂了这个就不用看了

img

img

img

img

img

img

依次类推

4>计算next值

接下来将maxL复制一行,去掉最后一个数,在开头添加一个-1,向右平移一个格,然后每个值在加1的到next值

img

img

5>计算nextVal值,首先将第一个为0,然后看next和maxL是否相等(先计算不相等的)

当next和maxL不相等时,将next的值填入

img

当next和maxL相等时,填入对应序号为next值得nextVal值

img

img

img

所以整个nextVal值为:

img

posted @ 2021-11-28 00:16  EEvinci  阅读(22)  评论(0编辑  收藏  举报