算法合集之《寻找最大重复子串》.doc
《算法合集之《寻找最大重复子串》.doc》由会员分享,可在线阅读,更多相关《算法合集之《寻找最大重复子串》.doc(15页珍藏版)》请在咨信网上搜索。
1、(完整版)算法合集之寻找最大重复子串寻找最大重复子串江苏金陵中学 林希德【关键字】后缀树 KMP推广算法 最优子串 【摘要】关于字符串处理,无论是国内的个大竞赛还是中文的经典宝书,都相对较少涉及.曾见各位高手在信息学论坛上就某前辈提出的此类问题讨论得热火朝天,于是我决心翻阅多方资料仔细研究,仅望对大家发表高见起抛砖引玉的小作用。本文第一章给出了问题的详细描述和我对该问题的拙见,第二、三章简述了字符串处理的两个常用算法-后缀树和KMP,第四章阐明了寻找最大重复子串的主算法。目录一 问题提出和初步认识1.1问题描述1.2初步分析二 后缀树2.1后缀树的定义2.2后缀树的构建2。3后缀链接2。4性能
2、分析三 模式匹配3.1朴素模式匹配3。2 KMP模式匹配3。3前缀函数3。4性能分析3。5 KMP推广算法四 主算法4。1问题转化4。2字符串分解4。3范围限定4.4找到循环节4。5辅助函数4.6性能分析五 论文小结正文一 、问题提出和初步分析1。1章节 定义一:对于字符串S,如果存在正整数p使得1 x S| p:S x = S x + p.那么称p是S的循环周期(Period),e = |S / p是S的指数(Power),任何长度为p的S的子串都是S的一个循环节(Repetend),特别的,当e 2时,S是个大小为p的重复字符串(Repetition or P-power word).问题
3、描述:给出一个由大写字母组成的字符串W,W长度为1 n 105,请你在W的所有子串中找出循环周期最长的那个重复字符串(Finding Maximal Repetition),即最大重复子串.1.2章节定义二:为方便表达,我们用符号W(u,v)表示开始于位置u结束于位置v的W的子串。初步分析:一个O(n2)的算法是乍一看最直观的收获。我们可以首先从n到1枚举循环周期p,然后针对p从位置1到n搜索重复子串,一旦找到立即输出并退出循环,如下:For p = n 1 do For i = 1 n doIf i p并且 Wi = Wi-p thenGi = Max(Gi1 + 1,1)Else Gi =
4、 0 End if If Gi = p then 输出W(i2p+1,i);退出循环End forEnd for这个O(n2)的算法简单易编,但速度较慢。那么,怎样让复杂度从O(n2)降到O(n)呢?为说清楚这个线性算法,我们不得不先介绍一种关于字符串处理的数据结构后缀树,还有就是模式匹配的KMP。二、 后缀树2.1章节后缀树定义:令W = W + $,这样W的最后一个字符从未在前面的任何一个位置上出现过。添置$的目的,将在下一小节中予以说明。后缀树其实就是一棵检索树(Trie),和普通检索树一样我们不断往树中插入字符串和添置顶点,只不过,后缀树还有一些特殊的性质: )我们从大到小依次往树中插
5、入W的后缀,这其实是后缀树的名称由来,也是它的构建过程。)树上每条边E(u,v)有两个参数和,记为E(u,v) = (,),代表子串W(,)。)树上每个节点均有26个儿子,代表26个大写字母.如果父亲节点u的第1个儿子是节点a,那么E(u,a)上的子串一定以字母A开头;如果第2个儿子是节点b,那么E(u,b)上的子串一定以字母B开头以此类推.定义三:如果从根Root到节点x途径若干条边,将这些边上的子串顺次连接得到字符串Sx,那么称Sx是x的对应子串,x是Sx的对应节点。易知,“节点对应子串” 和 “字符串对应节点” 都是一一映射的关系。)后缀树有n个叶子节点Leaf1、Leaf2 Leafn
6、,Leafi的对应子串实际就是W的后缀W(i,n)。这一点通过性质)就可以得到,这里无非明确一下.2。2章节定义四:Headi是W(i,n)和W(j,n)的最长公共前缀,其中j是小于i的任意正整数,Taili使得Headi + Taili = W(i,n)。定义五:只要子串S = W(u,v)满足u x,我们就说S在范围x内出现过.Headi其实就是在范围i-1内出现过的W(i,n)的最长前缀。初始化后缀树为只有根结点的树For i = 1 n do找到Headi的对应节点hi;增加叶节点Leafi,使得E(hi,Leafi) = (Headi+1,n) ;End for后缀树的构建:举例一:
7、下面让我们来看看字符串W = “AGATAGAG$的后缀树被逐步构建的具体例子,其中黑色圆圈是叶节点,圆括号内的是边参数(,):增加Leafi只是O(1)的工作,关键问题是如何找到Headi的对应节点hi。最直观也是最野蛮的方法是从根节点开始对W(i,n)实行逐个字符地扫描:hi = Find(Root,W(i,n) ;Function Find(实参:开始节点p;字符串S):指针类型;While true doe = p的第ord(S1) 64个儿子节点;If e不存在 then 返回指针p,Break;End if逐个字符比较找出S与E(p,e)的最长公共前缀UL = |U|IF L|S|
8、 thenp = eS = S(L+1,S)Else增加新节点q,令V = E(p,e)令q成为p的儿子,E(p,q) = V(1,L)令e成为q的儿子,E(q,e) = V(L+1,|V|)返回指针q,Break;End ifEnd whileEnd function请看 处,或许你会担心V(L+1,|V)可能是个无意义的空串,其实,L = V|的情况一定不会出现。反证法一:如果L = |V|,那么就说明W(i,n)是某个W(j,n)(1ji)的前缀,也就是说W的末尾字符$至少出现过两次。这与刚才 处的规定违背。 故,任何增添进后缀树中的边都不是空串。这种野蛮的扫描算法使得时间复杂度高达O(
9、n2),还外加一个不小的常数因子。其实,这个Find函数并不是完全的没有用处,只是,为加快寻找hi的速度我们需要使用辅助结构后缀链接。2.3章节后缀链接的定义(McCreight Arithmetic):令Headi1 = az,其中a是字符串W的第i1位字符。由于z在范围i内出现过至少两次,所以一定有|Headi| |z|,z是Headi的前缀.所谓hi-1的后缀链接(Suffix Link)实际是由hi1指向z对应节点d的指针Link hi-1。当然,z有可能是空串,此时Link hi-1由hi-1指向根节点Root.创建方法:通过后缀链接,我们在O(1)时间内找到节点d,然后再使用函数F
10、ind(d,W(i+|z,n)找到hi,速度自然要快很多倍。现在的问题是,怎样在每次建立节点hi后创建Link hi呢?规定:1) 根节点Root的后缀链接指向它自身2) 任何一个非叶节点的后缀链接都在该节点出现以后被立即创建根据这两条规定,hi的父亲节点c的后缀链接一定存在。我们从Link c出发,向下搜索,即可找到z的对应节点d。举例二:下面让我们来看看字符串W = “AAAA$”是如何利用后缀链接加快寻找hi的速度的。图中,虚线箭头表示相应节点的后缀链接,黑色圆圈是叶子节点,红色圆圈是当前后缀链接指向的节点。创建后缀链接的伪代码如下:p = hiWhile Link p不存在 doc =
11、 p的父亲节点V = E(c,p)If c = Root thenLink p = Down(Link c,V(2,V)ElseLink p = Down(Link c,V)End ifp = Link pEnd while函数Down的伪代码如下:Function Down(实参:开始节点p;字符串S):指针类型;While true doe = p的第ord(S1) 64个儿子节点;If e不存在 or S是空串 then 返回指针p,Break;End ifL = Min(|S,E(p,e))IF L |S thenp = eS = S(L+1,|S)Else增加新节点q,令V = E(
12、p,e)令q成为p的儿子,E(p,q) = V(1,L)令e成为q的儿子,E(q,e) = V(L+1,V|)返回指针q,Break;End ifEnd whileEnd function观察一下就会发现,函数Down和Find几乎一模一样,只不过 处,L不是通过逐个的字符比较而是直接的长度比较得出。为什么呢?反正法二:令L = |S和E(p,e)的最长公共前缀|。如果L Min(|S|,|E(p,e)|),那么就证明z在范围i内从未出现过。这于 处的结论矛盾.故,逐个字符比较的结果一定是L = Min(S|,|E(p,e)|)。2.4章节算法主框架回顾:回顾和整理一下算法主框架,看看我们究竟
13、做了些什么?For i = 1 n do步骤1、函数Find从Link hi1开始向下搜索找到节点hi步骤2、增添叶子节点Leafi步骤3、函数Down创建hi的后缀链接Link hi End for后缀树性能分析:接着刚才文本框内的伪代码来谈论.对于给定的i,步骤2的复杂度为O(1),但由于无法确定Link hi1到hi之间的节点个数,所以不能保证步骤1总是线性的.局部估算失败,不妨从整体入手。有一点是肯定的,那就是i + |Headi|总随着i的递增而递增。因此,W中的每个字符只会被Find函数遍历1次,总体复杂度是O(n)的.三、模式匹配的KMP算法如何判断字符串T(称T为模式)是否是字
14、符串S(称S为主串)的子串呢?至今为止,解决这个问题最优秀的算法是1xxx年由D.E。Knuth、J。H.Morris和V.R。Pratt共同提出的模式匹配KMP算法。大多数选手早已熟练掌握KMP,故,我在此仅为论文的完整性对它进行简要叙述。3。1章节为方便说明,我们令n = |S|,m = |T|。朴素的模式匹配算法朴素模式匹配的基本思想是:将主串S的第一个字符和模式T的第一个字符进行比较,若相等则进一步比较二者的后续字符;否则,从S的第二个字符开始重新和T的第一个字符进行比较以此类推,直至模式T和主串S中的某一个子串相等,则称匹配成功,否则称匹配失败。该算法复杂度是O(nm),显然令我们很
15、不满意.3.2章节KMP模式匹配如果说索引指针指向了当前有待比较的S和T中的两字符,那么朴素模式匹配算法效率不高的主要原因就是没有充分利用匹配过程中已经得到的部分匹配信息,而任由索引指针回溯。KMP正是针对这点缺陷对朴素算法做了实质性的改进,它主要的思想是:当出现字符比较不相等时,让模式在主串上尽可能的向右滑动,然后接着进行比较。举例三:例如下图,其中,S = “a b a b c a b c a c b a b”,T = “a b c a c”,表示索引指针。3。3章节前缀函数一切问题集中在如何让模式T尽可能向右滑动上。假设当前索引指针正向右移动,在它指向字符 Tj 和 Si 时发现Tj S
16、i,那么对于一切正整数k(i j + 1 k n m + 1), 满足S(k,k + m) = T的必要条件(记为号)是k i 或者 T(1,i k)是T(1,j - 1)的后缀。为防止重复或者遗漏,模式T向右滑动的距离应当等于Minx:i j + 1 + x满足必要条件。因为空串T(1, i - i)一定是T(1,j - 1)的后缀,所以必要条件中的k i完全可以省略.KMP算法的核心就是:令j-1 = Maxx:T(1,x)是T(1,j - 1)的后缀,然后将模式T向右滑动,使得索引指针指向Si和T的第j-1 + 1个字符。i的大小与主串S并无关联,所以我们应该事先通过预处理求出并保存所有
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 寻找最大重复子串 算法 寻找 最大 重复
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【精***】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【精***】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。