、基本概念1、模式匹配(定位)设有主串S和子串T(将S称为目标串,将T称为模式串),在主串S中,从位置start开始查找,如若在主串S中找到一个与子串T相等的子串,则返回T的第一个字符在主串中的位置,否则返回-1。2、算法目的确定主串中所含子串第一次出现的位置(定位)3、算法种类BF算法(又称古典的、经典的、朴素的、穷举的)KMP算法21、Brute-Force算法的设计思想:?将主串S的第一个字符和模式T的第1个字符比较,若相等,继续逐个比较后续字符;若不等,从主串S的下一字符起,重新与T第一个字符比较。?直到主串S的一个连续子串字符序列与模式T相等。返回值为S中与T匹配的子序列第一个字符的序号,即匹配成功。否则,匹配失败,返回值–1。2、Brute-Force算法的实现typedefstruct { char str[MaxSize];int length; }String;二、Brute-Force算法3intBFIndex(String S, int start, String T) {int i = start, j = 0, v;while(i < && j < ){if([i] == [j]){i++;j++;}else{i = i-j+1; j = 0;}} if (j==) v=i-; else v=-1;return v; }43、BF算法的时间复杂度讨论:若n为主串长度,m为子串长度,则串的BF匹配算法最坏的情况下需要比较字符的总次数为(n-m+1)*m=O(n*m)最好的情况是:一配就中!只比较了m次。最恶劣情况是:主串前面n-m个位置都部分匹配到子串的最后一位,即这n-m位比较了m次,别忘了最后m位也各比较了一次,还要加上m!所以总次数为:(n-m)*m+m=(n-m+1)*m能否利用已部分匹配过的信息而加快模式串的滑动速度?能!而且主串S的指针i不必回溯!最坏情况也能达到O(n+m)请看请看KMPKMP算法算法!!5尽量利用已经部分匹配的结果信息,尽量让i不要回溯,加快模式串的滑动速度。例:三、KMP算法1、KMP算法设计思想:S=‘a b a b c a b c a c b a b’T=‘a b c a c’S=‘a b a b c ab c a c b a b’T=‘a b c ac’S=‘a b a b c ab c a c b a b’T=‘ab c a c’需要讨论两个问题:①如何由当前部分匹配结果确定模式向右滑动的新比较起点k?②模式应该向右滑多远才是高效率的?iiikka baa bckii6奇妙的结果:奇妙的结果:k k 仅与模式串仅与模式串TT有有关!关!请抓住部分匹配时的两个特征:两式联立可得:“TT00……TTk-1k-1””==‘‘TTj-kj-k……TTj-1j-1’’S=‘a b a b cabc a c b a b’T=‘abc a c’ik则T的k-1~0==S前i-1i-1~~i-k)i-k)位设目前打算与T的第k字符开始比较(1)(2)‘‘TT00……TTk-1k-1’’则T的j-1~j-k位==S前i-1i-1~~i-k)i-k)位ikjS=‘a b a b cab c a c b a b’T=‘a bc a c’刚才肯定是在S的i处和T的第j字符处失配‘‘TTj-kj-k……TTj-1j-1’’截取一段,但截取一段,但kk有限制,有限制,0<k<j0<k<jkk是追求的新起点是追求的新起点注意:j 为当前已知的失配位置,我们的目标是计算新起点k。式中仅剩一个未知数k,理论上已可解!7根据模式串T的规律:““TT00……TTkk-1-1””==““TTj-j-kk……TTj-1j-1””由当前失配位置j(已知) ,可以归纳计算新起点k的表达式。next[ j ]=-1 当j=0时max {k| 0<k<j且‘T0…Tk-1’=‘Tj-k…Tj-1’}0 其他情况注意:注意:(1)k值仅取决于模式串本身而与相匹配的主串无关。(2)k值为模式串从头向后及从j向前的两部分的最大相同子串的长度。(3)这里的两部分子串可以有部分重叠的字符,但不可以全部重叠。令k =next[ j ](k 与j 显然具有函数关系),则取T首与Tj处最大的相同子串新起点k怎么求?8next[j]next[j]函数表征着模式函数表征着模式TT中最大相同前缀子串和后缀子串中最大相同前缀子串和后缀子串(真子串)的长度。(真子串)的长度。可见,模式中相似部分越多,则next[j]函
第4章2 爱妃 来自淘豆网m.daumloan.com转载请标明出处.