实现顺序串的各种模式匹配算法
Posted hzyb2018
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现顺序串的各种模式匹配算法相关的知识,希望对你有一定的参考价值。
目的:掌握串的模式匹配算法(BF和KMP )设计
内容:编写一个程序exp4-3.cpp,实现顺序串的各种模式匹配运算,并在此基础上完成以下功能:
1、建立目标串s="abcabcdabcdeabcdefabcdefg"和模式串t="abcdeabcdefab";
2、采用简单匹配算法求t在s中的位置;
3、由模式串t求next数组值和nextval数组值;
4、采用KMP算法求t在s中的位置;
5、采用改进的KMP算法求t在s中的位置;
写在前面
今天学习了如何对顺序串相关的算法,主要是看老师的PPT,问题主要分两方面:
- 算法的理解
- 算法的实现
以下主要就从这两个方面进行讨论
算法的理解
这道题目主要涉及的算法有BF,KMP。这两个算法都是用来判定模式串t是否为目标串s的子串问题,其中BF算法感觉还挺简单的,就是从s的每一个字符开始依次与t的字符进行匹配
匹配过程如下:
-
[S: color{red}aquad aquad aquad aquad aquad b ]
此时i=0,y=0 s[0]=t[0]
i,j继续后移,即i++, j++,直到出现s[i]≠t[j]
2. $$S: aquad aquad aquad color{red}aquad aquad b$$
此时i=3,y=3 s[3]≠t[3] 匹配失败
i回退,j重置为0(i=i-j+1,j=0)
循环执行1,2步
3. $$S: aquad aquad aquad aquad aquad color{red}b$$
此时i=6,y=4 s[6]=t[4] 匹配成功!
总的说来,BF算法的关键在于匹配失败时对i,j的处理。
算法的实现
//BF算法
int BF(SqString s,SqString t)
{
int i=0,j=0;
while (i<s.length && j<t.length )
{
if(s.data[i]==t.data[j] )
{
i++;
j++;//继续匹配下一个字符,依次匹配
}
else
{
i=i-j+1;//主串的指针回溯
j=0;
}//进行下一次匹配
}
if(j>=t.length )
return (i-t.length );//返回匹配的第一个位置的下标,因为是依次进行匹配,所以最终i的值会有包含字串t的长度。
else return (-1);
}
在阅读这段代码的时候while语句里的循环条件:while (i<s.length && j<t.length )
不是很好理解,后来仔细检查发现i,j都是从0开始,那么它们代表的是字符串中字符位置的下标,取
0--(length-1)
//主函数
int main() {
SqString s,t;
char a[]="abcabcdabcdeabcdefabcdefg",b[]="abcdeabcdefab";
StrAssign (s,a);
StrAssign (t,b);
cout<<BF(s,t)<<endl;//输出结果
//类型声明,自定义函数
#define MaxSize 100
typedef struct
{
char data[MaxSize ];
int length;
}SqString;//此为非紧缩存储格式
void StrAssign(SqString &s,char cstr[])
{
int i;
for(i=0; i<(int)strlen(cstr); i++)
s.data[i]=cstr[i];
s.length=i;
}//字符串的生成
KMP算法的初步理解
既然都是匹配字符串,第一步都是相同的,置$$i=0,j=0$$,对比BF算法,唯一的区别的地方就是在s[i]≠t[j]时(即匹配失败时)对i,j处理的不同
此时,在t[j]字符前若找到k个字符使得
(t_0t_1...t_{k-1}=t_{j-k}t_{j-k+1}...t_{j-1}t_j)
即t[j]前有k个字符与t开头的k个字符相等,说明t[j]字符前已有k个字符被成功匹配,下一趟应从t[k]开始匹配,即置j为k(next[j]=k)
初读这段话,感觉真的是云里雾里,难以理解,怎么就匹配成功了呢?沉思许久,终于找到一个合理的解释
将上面那段话翻译一下:
即s[i]前有k个字符与t开头的k个字符相等,说明t开头的k个字符被成功匹配,因为此时s[i]与t[j]前的字符是已经匹配好了的。
小结
至此KMP算法的核心思想总算初步搞明白了,只是还有许多细节的地方感觉不是很懂,在算法实现的时候对求next数组部分感到难以理解,看来还是没有理解透彻,"革命尚未成功,同志仍需努力"呀
写在最后
这是笔者第一篇关于学习记录的博客,在写作过程遇到了许多问题,好在总算完成了,因为记忆力不好,希望以这种方式记录下自己的思考过程,最后,哪怕前路漫漫,也愿以笔为刃,与诸君共勉。
以上是关于实现顺序串的各种模式匹配算法的主要内容,如果未能解决你的问题,请参考以下文章