KMP算法的核心思想是利用已经得到的部分匹配信息来进行后面的匹配过程。
下标 | 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。
……
#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]; } }
<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'};