之前写过模式匹配的算法,写的比较随意粗糙,该算法考的蛮多的,记录下来方便以后查阅,归根到底,模式匹配法的核心就是跳表的生成了,具体参阅《算法导论》。
#include <iostream>
#include <string>
using namespace std;
class KMP
{
public:
void set_Nexttable(const char *pattern,const int &size)//得到模式串的完整前缀函数,由此得到跳转表
{
const int p_size=size;
int *pi=new int[size];
int k=0;
pi[0]=0;
for(int q=2;q<=p_size;q++)//q代表模式串的第几个元素,取下标时要减1;
{
while(k>0&&pattern[k]!=pattern[q-1])//!!!注意要减1
{
k=pi[k-1];
}
if(pattern[k+1]==pattern[q-1])
{
k++;
}
pi[q-1]=k;
}
//设置跳转表
next_table=new int[size];
for(int i=1;i<=p_size;i++)
{
next_table[i-1]=i-pi[i-1];
cout<<next_table[i-1]<<" ";
}
}
void KMP_match(const char *target,const char *pattern,const int size_target,const int size_pattern)
{
match_num=1;
for(int i=0;i<size_target; )
{
int tem_i=i;
for(int j=0;j<size_pattern;)
{
if(pattern[j]==target[tem_i])
{
if(j==size_pattern-1)
{
cout<<"第"<<match_num<<"次模式匹配成功!"<<endl;
cout<<pattern<<endl;
i=i+next_table[6];
match_num++;
break;
}
j++;//j代表当前匹配的个数
tem_i++;
}
else
{
i=i+next_table[j];
break;
}
}
}
}
private:
int *next_table;
int match_num;
};
int _tmain(int argc, _TCHAR* argv[])
{
cout<<"请输入一个模式串:"<<endl;
string pattern;
cin>>pattern;
KMP a;
int size=pattern.size();
a.set_Nexttable(pattern.data(),size);//设置模式匹配的跳表
cout<<"请输入目标串:"<<endl;
string target;
cin>>target;
int target_size=target.size();
a.KMP_match(target.data(),pattern.data(),target_size,size);
return 0;
}
输出结果会显示匹配成功的次数(目标串包含几个模式串)