提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、字符串暴力匹配算法
#include <iostream>
#include <string>
using namespace std;
int violent_match(string s,string p)
{
int slen=s.length();
int plen=p.length();
int i=0,j=0;
while(i<slen&&j<plen)
{
if(s[i]==p[j])
{
i++;
j++;
}
else
{
i=i-j+1;
j=0;
}
}
if(j==plen)
return i-j;
else
return -1;
}
int main()
{
string s,p;
cout<<"输入文本串:"<<endl;
cin>>s;
cout<<"输入模式串:"<<endl;
cin>>p;
int ans;
ans=violent_match(s,p);
cout<<"最终位置"<<ans<<endl;
return 0;
}
二、KMP算法
1.解析
求next数组
int getnext(char ch[],int next[],int ch_length)
{
next[1]=0;
int i=1,j=0;
while(i <= ch_length)
{
if(j == 0 || ch[i] = ch[j])
{
i++;
j++;
next[i]=next[j];
}
else
{
j=next[j];
}
}
}
/*
1、next[j+1]的最大值为next[j]+1。
2、如果Pk1!=Pj,那么next[j+1]可能的次大值为next[next[j]]+1,由此可以高效推出next[j+1].
*/
例如:模式串如下
j | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
p | a | b | a | b | a | c | |
next | 0 | 1 | 1 | 2 | 3 | 4 | 1 |
逐步调试:
i | j | 条件 | i | j | Next | |
第一次循环: | 1 | 0 | j=0成立 | 2 | 1 | next[2]=1 |
第二次循环: | 2 | 1 | j不为0且ch[i]=ch[j]不成立 | j=next[j]=0 | ||
第三次循环: | 2 | 0 | j==0成立 | 3 | 1 | next[3]=1 |
第四次循环: | 3 | 1 | ch[i]=ch[j]成立 | 4 | 2 | next[4]=2 |
第五次循环: | 4 | 2 | ch[i]=ch[j]成立 | 5 | 3 | next[5]=3 |
第六次循环: | 5 | 3 | ch[i]=ch[j]成立 | 6 | 4 | next[6]=4 |
第七次循环: | 6 | 4 | j不为0且ch[i]=ch[j]不成立 | j=next[j]=2 | ||
第八次循环: | 6 | 2 | j不为0且ch[i]=ch[j]不成立 | j=next[j]=1 | ||
第九次循环: | 6 | 1 | j不为0且ch[i]=ch[j]不成立 | j=next[j]=0 | ||
第十次循环: | 6 | 0 | j==0成立 | 7 | 1 | next[7]=1 |
2.代码
代码如下(示例):
#include <iostream>
#include <string>
using namespace std;
int kmp_match(string s,string p,int *next)
{
int slen=s.length();
int plen=p.length();
int i=0,j=0;
while(i<slen&&j<plen)
{
if(s[i] == p[j] || j == 0)
{
i++;
j++;
}
else
{
j=next[j];
}
}
if(j==plen)
return i-j;
else
return -1;
}
int comnext(string p,int next[])
{
int plen=p.length();
next[0]=-1;
next[1]=0;
int i=1,j=0;
while(i <= p.length())
{
if(j == 0 || p[i] == p[j])
{
i++;
j++;
next[i]=next[j];
}
else
{
j=next[j];
}
}
}
int main()
{
string s,p;
int next[100];
cout<<"输入文本串:"<<endl;
cin>>s;
cout<<"输入模式串:"<<endl;
cin>>p;
comnext(p,next);
cout << "最终位置"<< kmp_match(s,p,next) << endl;
return 0;
}