1、循环往复,直到到达S或者T字符串的结尾。如果是到达S串的结尾,则表示匹配失败,如果是到达T串的结尾,则表示匹配成功。BF算法优点:思想简单,直接,无需对字符串S和T进行预处理。缺点:每次字符不匹配时,都要回溯到开始位置,时间开销大。下面是BF算法的代码实现:bf.c#include stdlib.hstring.hintindex_bf(char*s,char*t,intpos);index_bf_self(charindex);/*BF算法示例*/ main()chars=6he3wor;/标准BF算法中,s0和t0存放的为字符串长度。t=3worm=index_bf(s,t,2);/标准B
2、F算法printf(index_bf:%dn,m);m=index_bf_self(s,t,2);/修改版BF算法,s和t中,不必再存放字符串长度。index_bf_self:exit(0);字符串S和T中,s0,t0存放必须为字符串长度例:7hi baby!T=4babyindex_bf(s,t,1);pos:在S中要从下标pos处开始查找T(说明:标准BF算法中,为研究方便,s0,t0中存放的为各自字符串长度。)*/pos)i,j;if(pos=1&pos=s0-0i=pos;j=1;while(ijt0-returni-t0+-1;修改版,字符串s和t中,不必再包含字符串长度。hi ba
3、bybabyindex_bf_self(s,t,0);index:在s中,从几号下标开始查找index)i=index,j=0;while(si!=0while(*(t+j)! *(s+i+j)!if(*(t+j)!=*(s+i+j)break;if(*(t+j)=i;j=0;测试结果:二、KMP 算法:由BF算法例图中可知,当S8和T8不匹配时,S和T都需要回溯,时间复杂度高。因此,出现了KMP算法。先看下图:从图中,我们可以很容易的发现,S不必回溯到S1的位置,T也不必回溯到T0的位置,因为前面的字符,S和T中都是相等的。如果S不回溯的话,那T该怎么办呢?我们也可以很容易的发现,S中5、6
4、、7号字符和T中0、1、2号字符是相等的。故T直接回溯到T3的位置即可。此时我们就省去了很多不必要的回溯和比较。那么这些都是我们从图中直观得出的结论,如果换做其他字符,我们又如何知道T该回溯到几号字符呢?先看看KMP算法的思想:假设在模式匹配的进程中,执行Ti和Wj的匹配检查。若Ti=Wj,则继续检查Ti+1和Wj+1是否匹配。若TiWj,则分成两种情况:若j=1,则模式串右移一位,检查Ti+1和W1是否匹配;若1图中,首先构造 Next 数组,构造过程见图解(这里讲解的简单了些,本文重点是理清KMP算法思路,故没有赘述,想细究的同学,自己谷歌一下吧)。构造完毕后,当S8和T8失配时,我们从n
5、ext 数组可知,T应回溯到T3的位置,重新开始比较。样子有点像下面这样:如果S8和T3再次失配,则继续回溯,即比较S8和T0。如果再次失配,T已无回溯元素可言,此时,S向后移动,即开始比较S9和T0结束条件就是:到达字符串S或者T的结尾。若是S结尾,则返回-1.若是T结尾,则匹配成功。返回S中T串开始时的下标即可。下面给出个小例子,仅供大家练习使用:下面给出KMP算法标准代码(即数组首元素保存的是字符串长度):kmp.cvoidget_next(char*next);index_kmp(charmain(intargc,char*argv) char t=6ababcd int next7;
6、 get_next(t,next); int i; for(i=0;i7;i+) printf(%d,nexti);n);6helworm=index_kmp(s,t,1);利用KMP算法,求解字符串t在s中的开始位置。在字符串S中,从下标pos开始查找是否含有t子串如果含有,返回t在s中的下标起始位置。否则,返回-1.注意:s和t中首元素保存的都是字符串的长度。nextsizeof(t);get_next(t,next);if(0=j|si=tj)j=nextj;*next)i=0;next1=0;while(jif(0=iti=tj)if(ti!=tj)nextj=i;nextj=next
7、i;i=nexti;修改版KMP算法:(字符数组首元素不再保存字符串长度,更符合实际应用) kmp2.cmain(void)hello world!world int nextstrlen(t);strlen(t); m=index_kmp(s,t,0);在字符串s中,从下标index开始查找是否含有字符串t.如果有,返回t在s中的开始位置;如果没有,返回-1。(使用KMP算法实现)注:字符数组s和t中,不再保存字符串长度。nextstrlen(t);tj!continue;/从模式匹配数组中,获取要回溯到的结点if(0=j)/单独处理第一个字符if(tj=/表示字符串t中,所有字符已匹配完毕
8、i-strlen(t);/因为i以匹配至s中t字符串的结尾。因为要返回的是s中t的开始下标,故i-strlen(t).KMP算法之next数组代码next数组定义:当模式匹配串T失配的时候,next数组对应的元素知道应该用T串的哪个元素进行下一轮的匹配。/Prefix 前缀/Postfix 后缀next0=0;/自定义的,0和1都从0开始匹配while(tj!if(ti=tj)/若前后字符匹配,则向前推进/前后字符不匹配,则回溯。注意,此时是i和j不匹配,因此,根据next数组定义,要回溯到nexti的值。if(0=i)/当回溯到首字符时,单独进行处理next+j=+i;next+j=i;示例测试结果:
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1