1.BF算法
BF算法是从主串中找到子串,暴力解决问题,一一对比是否符合。
便于记载主串S中的起始位置,使用start记载。代码如下:
int BF(char s[],char t[])
{
int start=0;
int i=0.j=0;
while((s[i]!='\0')&&(t[j]!='\0'))
{
if(s[i]==t[j])
{
i++;
j++;
}
else
{
start++;
i=start;
j=0;
}
}
if(t[j]=='\n')
{
return start+1;
}
else
{
return 0;
}
}
2.KMP(看毛片)算法
自己总结kmp算法就两步:
1.首先求模式字符串的next值
2.根据next的值进行滑模式字符串,主串不需要动
求next的值方法如下:
怎么按照next的值进行滑动?算法思想如下:
举例滑行模式图如下:
1.
2.
3.
这里kmp算法,自己也是看了好久才搞懂,希望可以认真理解,多思考实践。
具体c++代码如下:
//s,t为模式串,在s中检查是否包含t,存在则返回起始位置,不存在则返回-1
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void getnext(const string &t,vector<int> next)
{
next.clear();
next.resize(t.size());
if (t.length()== 1)
{
next[0]=-1;
return ;
}
next[0]=-1;
next[1]=0;
int len= t.length();
int i=2,cn=0;//cn为最长前缀的后一个字符
while(i<len)
{
if (t[i-1]==t[cn]) //如果前一个字符和cn对应的值相等
next[i++]=++cn;//如果相等则此处的值为,cn+1
else if (cn>0)
cn=next[cn];//不等的话继续往前推
else
next[i++] =0;//不等的话并未没法往前推就变为0
}
}
int kmp( const string &s, const string &t,vector<int> & next)
{
int i1 = 0, i2 = 0;
while (i1<s.length() && i2<t.length())
{
if (s[i1]==t[i2])//两者比对,相等则主串和模式串都加加
{
i1++;
i2++;
}
else if (next[i2]==-1)//两者没有匹配则进一步判断i2是否还有回退的资格,如果等于-1说明已经退到头了,则只能i1++;
{
i1++;
}
else//还可以退,则i2回到到next数组指定的位置再进行比对
i2=next[i2];
}
return i2 == t.length()?i1-i2:-1;
//如果str2已经扫描完了说明已经找到了,返回str1中找到的起始位置;如果没有扫描完说明没有找到返回-1;
}
int main()
{
string s,t;
cin>>s>>t;
vector<int> next;
int k;
k=kmp(s,t,next);
return k;
}