bf算法难度一般,kmp算法难度一般但是其中的找next[j]的算法比较难,很多小伙伴不好听明白,
在这我推荐你们看这个链接的视频(https://www.bilibili.com/video/av714697013/)讲解的很明白
通过动画理解代码的意义,这个不好理解多看多思考
#include<iostream>
using namespace std;
#define max 100
int next[max];
typedef struct
{
char c[max + 1];
int length;
}sstring;
void fullstring(sstring& s)
{
int i = 1, t;
cout << "请输入串的数据长度" << endl;
cin >> t;
s.length = t;
for (i = 1; i <= t; i++)
{
cin >> s.c[i];
}
}
void bf(sstring& s, sstring& t)
{
int i=1, j=1;
while(j<=t.length&&i<=s.length)
{
if (s.c[i] == t.c[j])
{
i++;
j++;
}
else
{
i=i-j+ 2;
j = 1;
}
}
if (j >= t.length)
cout << "子串在主串中的位置为" << i-t.length << endl;//输出子串在主串的位置
else cout << "主串中没有找到子串" << endl;
}
void getnext(sstring& t, int* next)
{
int i = 0, j = 1;
next[1] = 0;
while (j < t.length)
{
if (i == 0 || t.c[i] == t.c[j])//第一次next[2]=1;
{
//j为一直往后的数组序列,i的功能是找最长前后坠,当没有最长前后坠,i=0,next[++j]=++1=next[1]+1=0+1=1;
//这句话要理解//只要没有最长前后坠则next[j]=1;
next[++j] = ++i;
}
else
{
i = next[i];
}
}
}//该函数把子串中的每一个数据的next值求出来。
//next[j]的意思是j前前坠和后坠相同最大的前坠位置加1;
void kmp(sstring& s, sstring &t)
{
int i = 1, j = 1;
int next[255];
getnext(t, next);
while (i <= s.length&&j<=t.length)
{
if (j==0||s.c[i] == t.c[j])
{
i++;
j++;
}
else
{
//不匹配时则j=next[j]
//next[j]含义是j前最长前后坠+1;
j = next[j];//j=1,next[j]=0,其他j=1,其他j=最大前坠+1;
}
}
if (j >= t.length)
{
cout << "子串在主串中的位置是" << i - t.length << endl;
}
else
cout << "没有找到主串中有该子串" << endl;
}
int strlen(sstring& s)
{
return s.length;
}
int main()
{
sstring s,t;
fullstring(s);//主串的定义
cout << "主串长度为" << s.length << endl;
fullstring(t);//子串的定义
cout << "子串的长度为" << t.length << endl;
bf(s, t);
kmp(s, t);
}