- 1、本文档共22页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
字符串匹配问题(本科生教材)
KMP算法;1、前缀函数;2、例2; c d a b a b a b a b ?; ? 当p.c[q]与t.c[j]不相等时,模式串p向右滑动多少个位置,再比较,既不丢失可能的匹配,又不做回溯?
以例2为例,展示匹配和滑动的过程!
1) 求p0,p1,…,pq-1中最大相同的前缀与后缀的长度k;
2) next[q]=k
即:
当p.c[q]与t.ch[j]不相等时,模式串p向右滑动q- k 个位置,继续比较p.c[q]和t.c[j]。;依次类推,直至出现下列两种情形之一。
(1) q退到某个next值,next[next…next[ ]]]时,比较i位置的字符,如相等,若此时若还不是完全匹配(q≠m),则q与j值各自增加1,继续比较下一字符
(2)如,k=-1时,模板退回到第1个位置、主串向前进一个,继续比较。
当算法中出现p.ch[q]=t.ch[i],且q=m时,显然找到了一个匹配p[0..m-1]=t[i-m..i-1]这是算法返回主串中出现匹配的第一个字符的位置i-m.;3、KMP算法;模板向后滑动 ;模板向后滑动 ;4、求前缀函数;由p的前缀函数的定义易知next[0]=-1 next[1]=0 。
用数学归纳法来计算前缀函数next的值:
对于任何q1,如果我们已经计算出:
next[0], next[1],…, next[q]
那么如何计算next[q+1]呢?
; 设next[q]=k,这意味着p[0..k-1]既是p[0..q-1]的一个真前缀,又是p[0..q-1]的一个真后缀且长度最长。
比较p[k]和p[q],可能出现两种情况:
① p[k]=p[q]
此时,p[0..k]是p[0..q]的后缀,且在即是真前缀又是真后缀的子串中它是长度最长的。
因此,由前缀函数的定义可知:
next[q+1]= next [q]+1
② 若p[k]≠p[q]。在这种情况下,我们要在p[0..q-1]中找第二大的真前缀和真后缀,next[next[q]]= next[k],显然next[k]kq。; 比较p[next[k]]和p[q],此时仍然可能出现两种情况。
①当p[next[k]]=p[q]时,与情形1)相同,可知:
next[q+1]= next[k]+1=next[next[q]]+1
②当p[next[k]]≠next[q]时,类似的,我们再找p[1..q-1]中第三大真前缀和真后缀。; 重复这个过程,直到为空,此时next[q]=-1; 或者p[1..q]中存在1个真前缀和真后缀,使得next[q+1]= next[next[…next [q]]]+1。; makeNext(PSeqString t, int * next)
{ int i,k;
k=-1; i=0;
next[0] = -1;
while( i p-n -1)
{ while( k=0 p-c[i] != p-c[k])
k = next[k];
i++; k++;
if (p-c[i] = = p-c[k])
next[i]=k;
}
} ; void get_next(SString T, int next[ ])
{ int i,j;
i =1; j=0;
next[1] = 0 ;
while( i T[0]){
if (j = =0 || T[i] = = T[j])
{
++i;
++j;
next[i] =j;
}
else j=next[j] ;
}
};5、KMP算法的复杂性;前缀函数的复杂性;同理KMP算法中:
while( i p-n j t-n)
if(i= = -1 || p-c[i] = = t -c[j] )
{ i++;j++;}
else
i=next[i];
累计计算的次数最多不超过O(m+n)。
算法KMP_MATCHER的总计算时间为O(m+n)。 ;6、KMP算法的改进; 算法KMP_MATCHER中比较p[q]和t[i]不相等,且p[q]=p[next[q]]时,不仅可以向右滑动q-next[q]个位置,而且更大一点,
文档评论(0)