kmp
蛮力算法
i++ j++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19/******************************************************************************************
* Text : 0 1 2 . . . i-j . . . . i . . n-1
* ------------------------|-------------------|------------
* Pattern : 0 . . . . j . .
* |-------------------|
******************************************************************************************/
int match ( char* P, char* T ) { //串匹配算法(Brute-force-1)
size_t n = strlen ( T ), i = 0; //文本串长度、当前接受比对字符的位置
size_t m = strlen ( P ), j = 0; //模式串长度、当前接受比对字符的位置
while ( j < m && i < n ) //自左向右逐个比对字符
/*DSA*/{
// /*DSA*/showProgress ( T, P, i - j, j ); getchar();
if ( T[i] == P[j] ) //若匹配
{ i ++; j++; } //则转到下一对字符
else //否则
{ i -= (j - 1); j = 0; } //文本串回退、模式串复位 // i j 都在往右走, i -= (j - 1) 相当于i在初始位置 又往右走了一步
/*DSA*/}
return i - j; //如何通过返回值,判断匹配结果?
}i , j++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18/******************************************************************************************
* Text : 0 1 2 . . . i i+1 . . . i+j . . n-1
* ------------------------|-------------------|------------
* Pattern : 0 1 . . . j . .
* |-------------------|
******************************************************************************************/
int match ( char* P, char* T ) { //串匹配算法(Brute-force-2)
size_t n = strlen ( T ), i = 0; //文本串长度、与模式串首字符的对齐位置
size_t m = strlen ( P ), j; //模式串长度、当前接受比对字符的位置
for ( i = 0; i < n - m + 1; i++ ) { //文本串从第i个字符起,与
for ( j = 0; j < m; j++ ) //模式串中对应的字符逐个比对
/*DSA*/{showProgress ( T, P, i, j ); getchar();
if ( T[i + j] != P[j] ) break; //若失配,模式串整体右移一个字符,再做一轮比对
/*DSA*/}
if ( j >= m ) break; //找到匹配子串
}
return i; //如何通过返回值,判断匹配结果?
}
数据结构下 第十三章 串
KMP算法
算法主体
KMP排除了三个位置
1 | int match ( char* P, char* T ) { //KMP算法 |
构建next表
1 | int* buildNext ( char* P ) { //构造模式串P的next表 |
https://www.bilibili.com/video/av3246487/
前缀 : 包含首位字符 但不包含末位字符的子串。
后缀: 包含末位字符但不包含首位字符的子串。
还一种理解
Prefix 长度为k的前缀 :起始于首字符的前k个字符
suffix 长度为k的后缀 : 终止与末元素的最靠后的k个字符
前缀
字符串 : ababacb
前缀集合 :不包括最后一个字符 a , ab , aba , abab , ababa, ababac
后缀集合 : 不包括第一个字符 , b, cb, acb,bacb,abacb,babacb
找到公共前后缀, 前缀移动到后缀的位置
kmp算法
了解了前后缀,再看这个视频,会很清晰
https://www.bilibili.com/video/BV1AY4y157yL
KMP字符串匹配算法1 讲解分析不错 ,视频2运行碰到一些问题,也没听懂
https://www.bilibili.com/video/BV1Px411z7Yo
【宫水三叶】简单题学 KMP 算法
LeetCode这个题解,分析能看懂,next数组构建也能看懂,但是不知道为什么是这样构建的, p[j] != p[i] ,为什么是 j = next[j-1]?
代码随想录
宫水三叶中的问题 ,但是不知道为什么是这样构建的, p[j] != p[i] ,为什么是 j = next[j-1]?
随想录下面有说到
为什么要前一个字符的前缀表的数值呢,因为要找前面字符串的最长相同的前缀和后缀。
关于随想录视频2,跟着他讲的代码流程走都清楚理解了,就是 next为什么回退, 原理没太明白.
有空听听他讲的
50分钟讲到回溯,比较清晰,不过用汉字比较看了感觉不太好
https://www.bilibili.com/video/BV1S64y1u74P
22分钟讲了回溯
https://www.bilibili.com/video/BV1CY4y14751
kmp优化偷懒技巧 中间加特殊符号# 连起来 没听懂
最终还是看随想录视频理解
i 后缀末位(从左到右) , j前缀末位(也是最长公共前后缀的长度)