BF算法
算法思路比较简单,跟KMP比简直幼儿园级别的,可以指定主串中查找的起始位置,每次匹配失败指针回溯主串指针i=i-j+1,子串指针j=1
#include <iostream>
using namespace std;
int Index_BF(string A, string B, int pos) {
int i = pos, j = 0;
while (i < A.length() && j < B.length()) {
//两个字符串均为比较到串尾(只有有一个到串尾就跳出循环)
if (A[i] == B[j]) {
i++;
j++;
}
else {
//匹配失败指针回溯
i = i - j + 1;
j = 0;
}
}
if (j >= B.length()) return i - B.length();
else return -1;
}
int main() {
string a = "abckjsef";
string b = "kjs";
int flag = Index_BF(a, b, 4);
if (flag == -1) cout << "子串在主串之中不存在!" << endl;
else cout << "子串在主串中起始位置为:" << flag + 1 << endl;
return 0;
}
KMP算法
有点难理解,研究了好长时间才恍然大悟,大概意思找子串每一节的前缀和后缀公共串,然后记录next中,匹配的时候通过前缀到后缀的滑动,不需要主串的指针回溯
具体解析可以参考这个:https://blog.csdn.net/qq_43656233/article/details/102604833
#include<iostream>
#include<cstring>
using namespace std;
//当k = -1,代表前面匹配失败,重新开始匹配。
//当T[k] == T[j],代表匹配成功,进行下一次的匹配。
//如果两个条件都不满足,让k = next[k],去next的位置,重新开始。
//next=前后缀最长公共部分+1
void setNext(string T, int next[])
{
int tlen = T.length();
next[0] = -1;
int j = 0, k = -1;
while (j < tlen)
{
if (k == -1 || T[k] == T[j])
{
k++;
j++;
next[j] = k;
}
else
{
k = next[k];
}
}
}
int getLocate(string S, string T, int next[])
{
setNext(T, next);
int slen = S.length();
int tlen = T.length();
int i = 0, j = 0;
while (i < slen && j < tlen)
{
if (j == -1 || S[i] == T[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j == tlen)
{
return i - tlen + 1;
}
return -1;
}
int main()
{
int next[100];
string s = "BBCSABCDABSABCDABCDABDE";
string t = "ABCDABDABC";
cout << getLocate(s, t, next);
return 0;
}