1、4.5.3 模式匹配 . 模式匹配的概念 设有给定的两个串T和P,则在T中寻找等于P的子串的过程,称为模式匹配,T称为正文(text),P称为模式(pattern)。 通常T长度远远大于P的长度,若在T中找到等于P的子串,则匹配成功;否则,匹配失败。,2简单的模式匹配算法 算法思想如下:对于i=0, 1, , n-m,依次执行下列匹配: 用p0, p1, , pm-1依次与ti, ti+1, , ti+m-1比较,若均对应相等,则匹配成功,整个算法结束;若存在某个k(0k m-1),使得pk ti+k,则立即结束这轮比较, 将模式P向右移动一位,再执行下一个i的新一轮匹配。 如执行了n-m+1
2、轮,即i从0到n-m的所有情况,在T中都没有找到P的子串,则匹配失败。,#define MAXN 100 #define MAXM 50 char tMAXN, pMAXM ; int simple_match ( t, p, n, m) char t , p ; int n , m ; int i , j , k ; for (i=0 ; i=n-m ; i+ ) for (j=0 ; k=i ; jm 简单模式匹配算法,在最坏的情况下,比较的总次数为:m(n-m+1) ,则时间复杂度为:O(mn)。,3模式匹配的KMP算法 由D.E.Knuth,J.H.Morris和V.R.Pratt三个
3、人提出来的。,Kunth-Morris-Pratt算法举例: T: a b c a b c a a b c a b c a b c d P: a b c a b c d (a b c)a b c d (a)b c a b c d a b c a b c d (a b c)a b c d,数据结构 第 4 章 数组和串 第 5 节 串,KMP(D.E.Knuth-J.H.Morris-V.R.Pratt)算法 t0 ti-j ti-j+1 ti-k ti-k+1 ti-1 ti ti+1 p0 p1 pj-k pj-k+1 pj-1 pj pj+1 ? p0 p1 pk-1 pk pk+1 如果
4、模式P的开头k个字符(p0, ,pk-1)依次与pj的前面k个字符(pj-k, ,pj-1)相同,那么可以省去烦琐的一轮轮的比较,还可省去模式的前k个字符的比较,只需从ti与pk开始依次继续进行比较。,数据结构 第 4 章 数组和串 第 5 节 串,数据结构 第 4 章 数组和串 第 5 节 串,在执行匹配过程中一旦出现tipj处失配,我们必须在模式P中找出一段p0p1pk-1 = pj-kpj-k+1.pj-1,这个k我们称pj的“失败链接值”,我们发现在寻找模式 P的各个字符的失败链接值与正文T无关,只依赖模式本身。 在进行匹配前,预先为模式P的每一个符号设置好它的失败链接值,一旦出现ti
5、pj处失配。那么就取出pj失败链接值k,而下次匹配直接将模式P的pk开始与正文失败处ti继续比较下去。,数据结构 第 4 章 数组和串 第 5 节 串,计算失败链接值数组元素(对应模式的下标 j),数据结构 第 4 章 数组和串 第 5 节 串,失败链接值的函数: #define MAXN 100 #define MAXM 50 char tMAXN, pMAXM ; int flinkMAXN; void faillink(char p , int flink , int m ) int j=1, k ; flink0 = -1 ; while (jm) k=flinkj-1 ; while
6、( k!=-1 / 时间复杂度分析为O(m),数据结构 第 4 章 数组和串 第 5 节 串,KMP算法 int kmp_match( t ,p , flink , n, m ) char t , p ; Int flink , n , m ; int i , j ; i=0 ; j=0 ; while( in) while( j!= -1 return (-1) / 时间复杂度分析为O(n),数据结构 第 4 章 数组和串 第 5 节 串,4模式匹配BM(Boyer-Moore)算法 BM算法与KMP算法差别在于: (1)在模式匹配时,不是自左向右进行,而是自右向左进行。 (2)事先计算一个
7、函数d(x),包含下列信息: 当x不在模式P中,或出现在P的尾端,则d(x)取值为模式P的长度。 其余情况,d(x)取值等于字符x在模式P中最右端的字符x到尾端的距离。,给定的模式P=p0p1p2.pm-1,模式P长度为m,则D(x)函数表示如下: m 若x不在P,或x=pm-1,但xpi (0im-2) d(x)= m-i-1 其余情况,这里i=max 例P=”doctor”,由d(x)函数求出,d(r)=6,d(o)=1,d(t)=2,d(c)=3,d(d)=5,其他不在模中的符号的值d(x)=6。,BM算法的思想: 假设在执行正文T中自第 i 起,与模式P开始自右向左的匹配,一旦发现不匹
8、配,则去执行pm-1与ti+d(ti)开始的自右向左的匹配,相当于把整个模P向右滑过d(ti)个一段距离。 若模式P在与正文第 i 位起的匹配过程中,假如中间某个符号与正文的符号不匹配,而 ti 不在模式中或是模的尾端,那么滑过的距离是最大的,也就是模P的长度m。,d(x): 6 6 1 4 正文: t h e n e l s e t u r n f a t h e r e t u r n r e t u r n r e t u r n r e t u r n r e t u r n r e t u r n,算法 #define MAXN 1000 #define MAXM 50 char tMAXN , pMAXM ; int n , m ; int d26 ; void dx(char p , int d , int m) / 建立d26数组 int i; for ( i=0 ; i26 ; i+ ) di=m ; for (i=0 ; i=0 / 匹配失败 ,