第四章串的模式匹配
暴力匹配算法(简单模式匹配)
分别用i和j指示长m的主串S和长n的模式串T中当前正待比较的字符位置。
从S第一个字符起,与模式T第一个字符比较,若相等则继续逐个比较后续字符,否则从主串的下一个字符起重新和模式的字符比较;以此类推直至模式T中的每个字符依次和主串S的一个连续的字符序列相等,则匹配成功。最坏时间复杂度O(mn);
KMP算法
暴力匹配算法低效率的根源是模式串在不断自我比较。
部分匹配值(PM表)
以’ababa’为例;
‘a’的其追后缀都是空集,最长相等前后缀长度为0;
‘ab’前缀为’a’,后缀为’b’,最长相等前后缀长度为0;
‘aba’, {a,ab}, {a,ba},{a},1;
‘abab’,{a,ab,aba},{b,ab,bab},{ab},2;
‘ababa’,{a,ab,aba,abab},{a,ba,aba,baba};{aba};3.
则其PM表为
发现不匹配时子串需要向后移动的位数:
移动位数 = 以匹配的字符数 - (最后一个匹配字符)对应的部分匹配值。
发生失配时,如果对应的部分匹配值为0,此时移动位数最大直接移动子串将首字符移到主串i位置进行比较。
改进(next数组)
PM表
next表
PM表右移一位 (空缺的用-1填充,最后一个元素的部分匹配值用于下一个元素,但没有下一个元素故可以舍弃) 并加一得到next表。
next表的含义是子串的第j个字符发生失配时跳到子串的next[j]位置重新与主串当前位置进行比较。
KMP算法的本质就是尽可能的让子串右移减少无意义的比较从而提高效率。
时间复杂度为O(m+n)。