求最长回文子串和最长重复子串.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
求最长回文子串与最长重复子串。 长沙雅礼中学 何林 【介绍】 问题的提出: 问题1 最长回文子串 顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。 输入长度为n的串S,求它最长回文子串。 问题2 最长重复子串 如果一个串x在S中出现,并且xx也在S中出现,那么x就叫做S的重复子串。 输入长度为n的串S, 本文主要涉及“最长回文子串”和“最长重复子串”这两个经典的信息学问题。把他们放在一起讨论,是因为两者的解法具有惊人的类似性。 从算法的最优性上说,两者都存在线性时间复杂度的算法——使用后缀树。无庸置疑,后缀树已经成了优化字符串处理类问题的不二法门。但是它有两个致命缺点。 后缀树的时空复杂度和字符串涉及的字符集有直接关系。称后缀树是“线性数据结构”也是建立在字符集规模为常数的假设上。因此,所谓“线性算法”,准确的说,只是“伪线性”。 实践后缀树的编程复杂度极高。如果说上一点是后缀树在理论上的硬伤,那么这一点就是后缀树在实践上的致命弱点。对时间要求很高的信息学竞赛,是不允许选手花数个小时去编写一个长而容易出错的程序的。最重要的一点是,因为字符集比较大,后缀树的实际运行效果往往不佳,甚至很容易发生空间上的爆炸。 以上两个原因限制了后缀树在竞赛中的应用,虽然它在理论上的价值是不可取代的。 一种折衷的数据结构——后缀数组——可以很好的平衡后缀树的缺点。但是其编程复杂度也不低。要求任意两个串的最长公共前缀,或者用RMQ算法、或者用线段树,这两只“老虎”都不是好惹的——几百行的程序一稍不留神就可能满盘皆错。 本文重点介绍的是一个有别于“后缀”系列的全新的算法:分治+扩展的KMP算法。它时空复杂度低,编程十分简单,而且算法原理非常好理解。更重要的是其解题思想有很深的可挖掘性。 【扩展的KMP算法】 问题的提出: 扩展的KMP问题 给定母串S,和子串T。定义n=|S|, m=|T|,extend[i]=S[i..n]与T的最长公共前缀长度。 请在线性的时间复杂度内,求出所有的extend[1..n]。 容易发现,如果有某个位置i满足extend[i]=m,那么T就肯定在S中出现过,并且进一步知道出现首位置是i——而这正是经典的KMP问题。 因此可见“扩展的KMP问题”是对经典KMP问题的一个扩充和加难。 来看一个例子S=’aaaaaaaaaabaaa’, T=’aaaaaaaaaaa’。 extend[1]=10 这里为了计算extend[1],我们进行了11次比较运算。 然后我们要算extend[2]: extend[2]=9。为了计算extend[2],我们是不是也要进行10次比较运算呢?不然。 因为通过计算extend[1]=10,我们可以得到这样的信息:S[1..10]=T[1..10](S[2..10]=T[2..10]。 计算extend[2]的时候,实际上是S[2]开始匹配T。因为S[2..10]=T[2..10],所以在匹配的开头阶段是“以T[2..10]为母串,T为子串”的匹配。 不妨设辅助函数next[i]表示T[i..m]与T的最长公共前缀长度。 对于这个例子,next[2]=10。也就是说: T[2..11]=T[1..10](T[2..10]=T[1..9](S[2..10]=T[1..9]。 这就是说前9位的比较是完全可以避免的!我们直接从S[11](T[10]开始比较。这时候一比较就发现失配,因此extend[2]=9。 以上的例子是有代表性。下面提出一般的算法。 设extend[1..k]已经算好,并且在以前的匹配过程中到达的最远位置是p。最远位置严格的说就是i+extend[i]-1的最大值,其中i=1,2,3,…,k;不妨设这个取最大值的i是a。(下图黄色表示已经求出来了extend的位置) 根据定义S[a..p]=T[1..p-a+1](S[k+1..p]=T[k-a+2..p-a+1],令L=next[k-a+2]。有两种情况。 第一种情况k+Lp,如下图: 上面的红色部分是相等的。蓝色部分肯定不相等,否则就违反了“next[i]表示T[i..m]与T的最长公共前缀长度”的定义。(因为next[k-a+2]=L,如果蓝色部分相等的话,那么就有next[k-a+2]=L+1或者更大,矛盾)。 这时候我们无需任何比较就可以知道extend[k+1]=L。同时a, p的值都保持不变,k(k+1,继续上述过程。 第二种情况k+L=p。如下图: 上图的紫色部分是未知的。因为在计算extend[1..k]的时候,到达过的最远地方是p,所以p以后的位置从未被探访过,我们也就无从紫色部分是否相等。 这种情况下,就要从S[p+1](T[p-

文档评论(0)

lyxbb + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档