// KMP(模式匹配).cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int indexsimple(string str1,string str2)//方法一: 简单算法(朴素匹配法),
//对一般字符匹配时还可以,但对二进制匹配时时间很大,时间复杂度最坏:len1*len2
{
int len1=str1.size();
int len2=str2.size();
int i,j;
i=0;
j=0;
while(i<len1&&j<len2)
{
if(str1[i]==str2[j])
{
i++;
j++;
}
else
{
i=i-j+1;
j=0;
}
}
if(j==len2)
return i-j;
else
return 0;
}
int indexrear(string str1,string str2)//首尾匹配算法,先比较模式串的第一个字符,再比较模式串的
//最后一个字符,再比较模式串的第二个至第len2-1个字符,最差时间为(len1*len2)
{
int len1=str1.length();
int len2=str2.length();
int i=0;
int j=1;
while(i<(len1-len2)+1)
{
if(str1[i]==str2[0])
{
if(str1[i+len2-1]==str2[len2-1])
{
i++;
while(j<len2-1)
{
if(str1[i]==str2[j])
{
i++;
j++;
}
}
if(j==len2-1)
return (i-j);
}
else
i++;
}
else
i++;
}
return 0;
}
//求的是待比较的字符串的get_nextval值,而不是主串的;,nextval[i]表示当str1[j]!=str2[i]时,当nextval[i]!=-1时,将str1[j]与str2[nextval[i]]比较
void get_nextval(string str2,int nextval[] )
{
int i=0;
int k=-1;
nextval[i]=-1;
while(i<(str2.size()-1))//导致string 越界
{
if(k==-1||str2[i]==str2[k])
{
i++;
k++;
if(str2[i]!=str2[k])
nextval[i]=k;
else
nextval[i]=nextval[k];
}
else
k=nextval[k];//得到前面有哪个str2[k]与str2[i]相等,以便得到str2[i+1]的值。
//nextval[i]表示的就是str2[k-1]=str2[i-1],但str2[k]!=str2[i];
}
}
int index_kmp(string str1,string str2,int nextval[])//KMP字符匹配法
{
int i=-1;
int k=-1;
int len1=str1.size();
int len2=str2.size();
get_nextval(str2,nextval);
while(i<(len1)&&k<(len2))
{
if(k==-1||str1[i]==str2[k])
{
i++;
k++;
}
else
k=nextval[k];
}
if(k==(len2))
return (i-k);
else
return 0;
}
int main()
{
string str1="abdabceoieioewnoie";
string str2="oewn";
int nextval[100];
get_nextval(str2,nextval);
cout<<indexsimple(str1,str2)<<endl;
cout<<indexrear(str1,str2)<<endl;
cout<<index_kmp(str1,str2,nextval)<<endl;
return 0;
}