引言:
KMP模式匹配算法在搜索与索引中是算法基础(?)
KMP匹配分两步:
1)根据要查找的字符串计算出next值;
2)利用next值来控制移动位置,实现高效匹配,不做多余的比较。
#include <iostream>
#include<string>
using namespace std;
//产生next值
void genKMPNext(int* next,string s)
{
int i=0;
int j=-1;
next[0] = -1;
while(i<s.length()-1)
{
while(j>=0&&s[i] != s[j])
j = next[j];
i++;
j++;
if(s[i] ==s[j])
next[i] = next[j];
else
next[i] = j;
}
}
//利用next值进行KMP算法
int KMP(string cs,string s)
{
int i;
int j;
int *next = (int*)malloc(sizeof(int)*s.length());
genKMPNext(next,s);
for (i=0,j=0;i<s.length()&&j<cs.length(); )
{
if (s[i]==cs[j])
{ i++;
j++;
}
else if(next[i]>=0)
i = next[i];
else
{
i=0;j++;
}
}
if(i>=s.length())
return j-s.length();
else
return -1;
}
//主函数部分
int main()
{
string cs="googlegood"; //一个长字符串
string s="good"; //目标串,即要在cs中寻找的字符串
int pos=KMP(cs,s); //找完后记录在cs的某个位置起
if(pos>=0)
cout<<"你匹配的字符串存在于原字符串的第"<<pos+1<<"个位置开始"<<endl;
else
cout<<"你匹配的字符串不存在"<<endl;
return 0;
}
当s="god"
---------------------------------------------------------2016.6.4更新,互动性地模式匹配-------------------------------
在ubuntu14.04编程实现:
#include<string>
#include<iostream>
#include<stdlib.h>
using namespace std;
void genNext(int *next,string s)
{
int i=0;
int j=-1;
next[0] = -1;
while(i<s.length()-1)
{
while(j>=0&&s[i]!=s[j])
j = next[j];
i++;
j++;
if(s[i]==s[j])
next[i] = next[j];
else
next[i] = j;
}
}
int Find(string cs,string s)
{
int i,j,*next = (int*)malloc(sizeof(int)*s.length());
genNext(next,s);
for(i=0,j=0;i<s.length()&&j<=cs.length(); )
{
if(s[i]==cs[j])
{i++;j++;}
else if(next[i]>=0)
i=next[i];
else
{i=0;j++;}
}
if(i>=s.length())
return j-s.length();
else
return -1;
}
int main()
{
string cs;
string s;
cout<<"请输入原始字符串:"<<endl;
cin>>cs;
cout<<"请输入要查找的子字符串:"<<endl;
cin>>s;
int len =s.length();
int next[len];
int pos = Find(cs,s);
if(pos>=0)
cout<<"所匹配的字符在原字符串从左往右数的第"<<pos+1<<"个位置开始出现"<<endl;
else
cout<<"你所匹配的字符串在源字符串中不存在"<<endl;
return 0;
}
匹配上和没匹配上的结果显示为: