字符串的模式匹配
寻找字符串p在字符串t中首次出现的起始位置
字符串的顺序存储
typedef struct
{
char str[MAXSIZE];
int length;
}seqstring;
朴素的模式匹配算法
基本思想:用p中的每一个字符去与t中的字符一一比较。
模式p 正文 t
如果匹配成功,则返回p在t中首次出现的起始位置
如果匹配不成功则返回-1
最坏情况比较次数可达:(n-m+1)*m次
int index(seqstring p,seqstring t)
{
int i,j,flag;
i=0;flag=0;
while((i<=t.length-p.length) && (!flag))
{
j=0;flag=1;
while(j<p.length && flag)
{
if(p.str[j]==t.str[i+j])
{
j++;
}
else
{
flag=0;
}
}
++i;
}
if(flag)
{
return (i-1);
}
else
{
return -1;
}
}
或者另一种朴素模式匹配算法
int index(seqstring t,seqstring p)
{
//t是文本串,p是模式串
int i=0,j=0;
while(i<t.length && j<p.length)
{
if(p.str[j]==t.str[i])
{
i++;
j++;
}
else
{
i=i-j+1;//需要琢磨
j=0;
}
}
if(j==p.length)
{
return (i-j);
}
else
{
return -1;
}
}
在学习KMP算法之前:
真前缀:除了自身以外,一个字符串的全部头部组合。
真后缀:除了自身以外,一个字符串的全部尾部组合。
(注意区分 前缀 和 真前缀)
KMP算法的流程:
假设现在文本串S匹配到i位置,模式串P匹配到j位置
如果j==-1 或者 当前字符匹配成功,则i++,j++,继续匹配下一个字符
如果匹配失败,那么模式串向右移动的位数:失配字符所在位置-失配字符对应的next值。
这时:j=6,next[j]=2,所以向右移动 j-next[j]=6-2=4个位置。
或者基于《最大长度表》:以匹配字符数-失配字符的上一位字符所对应的最大长度值
这时:以匹配字符为6,失配字符的上一位字符所对应的最大长度值=2,所以向右移动 6-2=4