数据结构–字符串的KMP算法
朴素模式匹配算法:
一旦发现当前这个子串中某个字符不匹配,就只能转而匹配下一个子串(从头开始)
但我们可以知道:
不匹配的字符之前,一定是和模式串一致的
\color{red}不匹配的字符之前,一定是和模式串一致的
不匹配的字符之前,一定是和模式串一致的
我们可以利用这个信息进行优化查找,我们知道一定无法匹配的就无需再进行匹配操作了
我们可以发现:
对于模式串T = ‘abaabc’
当
第
6
个
\color{red}第6个
第6个元素匹配失败时,可令主串指针
i
不变
\color{red}i不变
i不变,模式串指针
j
=
3
\color{red}j=3
j=3
当
第
5
个
\color{red}第5个
第5个元素匹配失败时,可令主串指针
i
不变
\color{red}i不变
i不变,模式串指针
j
=
2
\color{red}j=2
j=2
当
第
4
个
\color{red}第4个
第4个元素匹配失败时,可令主串指针
i
不变
\color{red}i不变
i不变,模式串指针
j
=
2
\color{red}j=2
j=2
当
第
3
个
\color{red}第3个
第3个元素匹配失败时,可令主串指针
i
不变
\color{red}i不变
i不变,模式串指针
j
=
1
\color{red}j=1
j=1
当
第
2
个
\color{red}第2个
第2个元素匹配失败时,可令主串指针
i
不变
\color{red}i不变
i不变,模式串指针
j
=
1
\color{red}j=1
j=1
当
第
1
个
\color{red}第1个
第1个元素匹配失败时,匹配下一个相邻子串,令
j
=
0
,
i
+
+
,
j
+
+
\color{red}j=0, i++, j++
j=0,i++,j++
再来一个Eg:
代码实现
typedef struct
{
char ch[15];
int length;
}SString;
int Index_KMP(SString S, SString T, int next[])
{
int i = 1, j = 1;
while (i <= S.length && j <= T.length)
{
if (j == 0 || S.ch[i] == T.ch[j])
i++, j++; //继续比较后继字符
else
j = next[j]; //模式串向右移动
}
if (j > T.length)
return i - T.length;
else
return 0;
}
n e x t 数组只和短短的模式串有关,和长长的主串无关 \color{red}next数组只和短短的模式串有关,和长长的主串无关 next数组只和短短的模式串有关,和长长的主串无关
时间复杂度
KMP算法,
最坏时间复杂度
O
(
m
+
n
)
\color{red}最坏时间复杂度O(m+n)
最坏时间复杂度O(m+n)
其中,求next 数组时间复杂度O(m)
模式匹配过程最坏时间复杂度O(n)