一、基本概念
两个字符串是否,其中一个是否在另一个中出现过呢,由此来进行探索
1.字符串匹配模式
字符串匹配模式是指一个字符串s中是否存在子串t,如果存在,返回t在s中的位置,否则返回-1
2.其他概念
前缀:以字符串的第一个字符为首字符的子串为字符串的前缀
后缀:以字符串的最后一个字符为尾字符的子串为字符串的后缀\
二、朴素模式匹配算法(BF算法)
从首字母一个个从进行比较,也许是最容易想到的一种方法
1.基本思想
从主串的第一个字符开始,依次判断以每一个字符作为起点的子串是否与模式串t匹配
2.算法1-1
功能:判断一个字符串t是否是主串s的子串
思路:
(1)定义一个变量k,表示每一轮主串的开始位置,当进入下一轮时,k增加1
(2)在每一轮的匹配中,定义两个变量i和j,初始值分别为k和0,进行这一轮的判断,如果s[i]=t[j]
,则i和j同步增加,否则进入下一轮
(3)当j到达模式串的最后一个元素的下一个位置时,匹配成功
3.示例
当s=“ababcab”,t="abc"时,判断t是否是s的子串
#include<iostream>
using namespace std;
//朴素模式匹配算法,判断主串s中是否包含模式串t
int bf(string s, string t) {
int i = 0, j = 0, k = 0;
while (i < s.size() && j < t.size()) {
if (s[i] == t[j]) {
++i, ++j;//i,j同步后移
if (j == t.size())return k;//j到达模式串的最后一个字符的下一个位置,匹配成功
}
else {
++k, i = k, j = 0;
}
}
return -1;
}
int main() {
string s = "ababcab", t = "abc";
cout << bf(s, t) << endl;
}
三、KMP算法
对于BF算法,t字符串不停的回退到开头的位置非常的浪费效率,因为t字符串很可能自身就存在重复,所以如果能够根据t字符串自身重复的情况进行不同程度回退,就可以提高效率
1.回退数组
1.含义
在进行模式匹配的时候,当s[i]!=t[j]
的时候,只需要将j回退到适当的位置即可,假设移动到next[j],next数组是由模式串决定的,值为模式串t的子串t[0,j-2]的前缀与子串t[1,j-1]的后缀相同的子串的最大长度,即 n