4.3模式匹配-KMP算法
详细介绍:参考http://blog.csdn.net/v_july_v/article/details/7041827
KMP算法特征:不需回溯指针i,一口气走到底。
j指针走的形式,符合next[ j ]函数;
(1)KMP算法来历
Knuth-Morris-Pratt 字符串查找算法,简称为 “KMP算法”,常用于在一个文本串S内查找一个模式串P 的出现位置,这个算法由Donald Knuth、Vaughan Pratt、James H. Morris三人于1977年联合发表,故取这3人的姓氏命名此算法。
(2)KMP算法
int Index_KMP(char *s,char *p)
{
int i , j;
int sLen = strlen(s);
int pLen = strlen(p);
i = j = 0;
while(i < sLen && j < pLen)
{
if(j == -1 || s[i] == p[j])//首位不匹配 || 相匹配
{
i ++;
j ++;
}
else
{
j = next[j];//提示:右移位数为 j - next[j]
}
}
if(j == pLen)
return i - pLen +1;
else
return -1;
}
(3)模式匹配
# include <stdio.h>
# include <string.h>
void Init_string(char *s,char *p);
int Index_KMP(char *s,char *p);
void get_next(char *p);
void print(int i);
int next[50];
int main()
{
int i;
char s[50];
char p[50];
Init_string(s,p);
get_next(p);
i = Index_KMP(s,p);
print(i);
return 0;
}
void Init_string(char *s,char *p)
{
printf("input string s , p:\n");
gets(s);
gets(p);
}
void get_next(char *p)
{
int i, j;
int pLen = strlen(p);
next[0] = -1;//按定义首位赋值-1
for(i = 0,j = -1; i < pLen; )
{
if(j == -1 || p[i] == p[j])
{
++ i;
++ j;
if(p[i] != p[j])
next[i] = j;
else
next[i] = next[j];//因为 不能出现p[i] == p[next[i]]
} //所以 继续递归,next[i] = next[j]
else
{
j = next[j];
}
}
}
int Index_KMP(char *s,char *p)
{
int i , j;
int sLen = strlen(s);
int pLen = strlen(p);
i = j = 0;
while(i < sLen && j < pLen)
{
if(j == -1 || s[i] == p[j])//首位不匹配 || 相匹配
{
i ++;
j ++;
}
else
{
j = next[j];//提示:右移位数为 j - next[j]
}
}
if(j == pLen)
return i - pLen +1;
else
return -1;
}
void print(int i)
{
if(i == -1)
printf("String p not be found !\n");
else
printf("The pos is: %d\n",i);
}
(4)性能分析
/*时间复杂度:O(m + n)*/
/*空间复杂度:O(n)*/
参考:http://blog.csdn.net/v_july_v/article/details/7041827