KMP算法
我们知道,串类型有一个功能是查找子串,而查找的方法有多种,如暴力查找法、KMP算法,这次我们来介绍一下这些方法
首先说明一下一些符号及名词的含义:
- S为主串
- T为待查找的子串,也称为模式串
- 子串在主串中的位置: 子串在主串中第一次出现时首字母在主串中的索引位置,即子串在主串中的位置。对于主串“to be or not to be ,This is a question”,子串“be”在子串中的位置为3
- 查找子串,即从主串中查找子串是否存在,如果存在返回子串在主串中的位置
- 字符串的前缀:对于字符串A和B,若存在A=BS,B、S为任意非空字符串,则称B为A的前缀。如字符串“Pig”,其前缀包括{“P”, “Pi”}
- 字符串的后缀: 对于字符串A和B,若存在A=SB,B、S为任意非空字符串,则称B为A的后缀,如字符串“Pig”,其后缀包括{“g”, “ig”}
- i、j 分别代表当前匹配到的主串位置和子串位置
- 此外,在本文中,数组的索引一律从0开始
暴力查找
暴力查找的步骤为:
if (S[i] == P[j])
{
i++;j++
}
else
{
i = i - j + 1;
j = 0;
}
其文字表述为:
- 从主串的首字符开始,与子串的每个字符 逐一进行比较
- 若遇到不匹配的字符,则将当前首字符的下一个字符作为首字符
- 重复步骤1,步骤2,直到寻找到子串或者扫描完整个主串(其中,i、j表示主串和子串当前比较的位置)
举个栗子:如下图,我们要寻找“ABCE”在“ABCABCDHIJK”中的位置
-
S[0] == P[0], 执行i++;j++ ,比较S[1]与P[1]
-
S[1] == P[1], 执行i++;j++ ,比较S[2]与P[2]
-
S[2] == P[2], 执行i++;j++ ,比较S[3]与P[3]
-
S[3] != P[3], 执行 i = i - j + 1;j=0; 得到i=1, j=0,重新开始比较;
-
S[1] != P[0],执行 i = i - j + 1;j=0; 得到i=2, j=0,重新开始比较;
-
S[2] != P[0],执行 i = i - j + 1;j=0; 得到i=3, j=0,重