1. 算法思想
KMP算法的核心思想是利用已经得到的部分匹配信息来进行后面的匹配过程。
2. 实例如下所示:
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
S | a | b | a | b | a | a | a | b | a | b | a | a |
next[] | -1 | 0 | 0 | 1 | 2 | 3 | 1 | 1 | 2 | 3 | 4 | 5 |
S串长度为0时,next[0] = -1。
S串长度为1时,next[1] = 0。
S串长度为2时,S串为"ab",next[2] = 0。
S串长度为3时,S串为"aba",next[3] = 1。
S串长度为4时,S串为"ab ab",next[3] = 2。
S串长度为5时,S串为"ababa",next[3] = 3。
……
3. 完整代码
#include <iostream>
using namespace std;
#define maxSize 20
typedef struct//定义字符串结构体
{
char *ch;
int length;
}Str;
int strassign(Str& str,char* ch);//字符串赋值操作
void getnext(Str substr,int next[]);//得到子字符串的next[]
int kmp(Str str,Str substr,int next[]);//KMP算法
void main()
{
Str str,substr;
str.ch = (char*)malloc(sizeof(char));//结构体初始化,指针要分配空间
str.length = 0;
substr.ch = (char*)malloc(sizeof(char));
substr.length = 0;
strassign(str,"ababcabcacbab");//赋值
strassign(substr,"abcac");
int next[maxSize];
getnext(substr,next);
int k = kmp(str,substr,next);
cout<<"在位置"<<k<<"处匹配"<<endl;
}
//赋值操作
int strassign(Str& str,char* ch)
{
if(str.ch)
free(str.ch);
int len = 0;
char *c = ch;
while(*c)//计算字符串长度
{
++len;
++c;
}
if(len==0)
{
str.ch = NULL;
str.length = 0;
return true;
}
else
{
str.ch = (char*)malloc(sizeof(char)*(len+1));//为了多分配一个空间存放“\0”字符
if(str.ch==NULL)
{
return false;
}
else
{
c = ch;//赋值操作
for(int i=0;i<=len;++i,++c)
str.ch[i] = *c;
str.length = len;
return true;
}
}
}
//KMP算法
int kmp(Str str,Str substr,int next[])
{
int i=0,j=0;
while(i<str.length&&j<substr.length)//主串或子串之一遍历完则结束
{
if(str.ch[i]==substr.ch[j])
{
++i;
++j;
}
else
{
j = next[j];
if(j==-1)
{
j = 0;
++i;
}
}
}
if(j==substr.length)
return i-substr.length;
else
return -1;
}
//求next数组算法如下
void getnext(Str substr,int next[])
{
int i = 0,j = -1;
next[0] = -1;
while(i<substr.length)
{
if(j==-1||substr.ch[i]==substr.ch[j])
{
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}
4.C++中使用结构体编程时注意的以下几点:
①方法中的结构体赋值多使用引用或指针。<pre name="code" class="cpp">int strassign(Str& str,char* ch);
②结构体使用应先初始化,即分配空间。
<pre name="code" class="cpp">Str str;
str.ch = (char*)malloc(sizeof(char));//结构体初始化,指针要分配空间
str.length = 0;
str.ch = (char*)malloc(sizeof(char)*(len+1));//为了多分配一个空间存放“\0”字符
③字符型指针与数组相同,即char *c与char c[]同。
typedef struct//定义字符串结构体
{
char *ch;
int length;
}Str;
for(int i=0;i<=len;++i,++c) str.ch[i] = *c;
char[] s = {'a','x','b','d','e','b','p','q','a','w','u','v','a'};