单模式串匹配----浅谈kmp算法
2021-05-20 15:28
标签:src 直接 opened name 复杂 sssss i++ display har 模式串匹配,顾名思义,就是看一个串是否在另一个串中出现,出现了几次,在哪个位置出现; p.s. 模式串是前者,并且,我们称后一个 (也就是被匹配的串)为文本串; 在这篇博客的代码里,s1均为文本串,s2均为模式串; 一般地,文本串长度不小于匹配串;(否则无意义) 很显然可以得到一个暴力的做法 : 时间复杂度:O ( TLE ) ------ O (N+M) ~ O(N*M) 所以需要一个更优的算法; 可以发现,在枚举匹配串在文本串中的开始位置时,有很多步骤是无效的,因为匹配串的第一个字符 很有可能和当前枚举到的开始位置 不同; 所以可以优化这个过程,每次改变开始位置时,直接移动到下一个和匹配串第一个字符相同的位置 (类似于链表; 这个做法看起来很强,实际上很容易被卡成O (n^2); 比如说 :s1 :sssssssssssssa, s2 : sssb; 由于并没有利用所有已经匹配过的部分,所以仍然会T; 于是,就有了KMP算法。 p.s. i表示当前在文本串中枚举到的位置,j表示模式串中的; 在s1[ i ] != s2 [ j ]时,将 j 移动到一个在 j 之前的位置k 使得 s2[ 1 ]~s2[ k ] 与 s2[ j-k+1 ]~s2[ j ]完全相同,那么时间复杂度就是O (N+M) 的了; p.s. 因为 i , j 两个指针最多移动N+M次; 给一个写模板的链接 :https://www.luogu.org/problemnew/show/P3375 贴代码 : 单模式串匹配----浅谈kmp算法 标签:src 直接 opened name 复杂 sssss i++ display har 原文地址:https://www.cnblogs.com/15owzLy1-yiylcy/p/9740396.htmlfor i : 1~lenth_of_s1 {//枚举匹配串在文本串中的开始位置
for j : 1~lenth_of_s2
if(s2[j]!=s1[i+j-1]) break;
if j>lenth_of_s2 //在循环结束前没有break
output : i
}
int next[N], pos=-1;
char head = s2[1];
for i : lenth_of_s1~1
if s1[i]==head {
next[i] = pos;
pos = i;
}
next[0] = pos;
for i = next[0] ; i != -1 ; i = next[i] {
for j : 1~lenth_of_s2
if(s2[j]!=s1[i+j-1]) break;
if j>lenth_of_s2 //在循环结束前没有break
output : i
}
// luogu-judger-enable-o2
// 15owzLy1
//luogu3375_kmp.cpp
//2018 10 02 17:27:50
#include
下一篇:什么是python??