论文--后缀数组.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文档。上传文档
查看更多
后缀数组 【作者】   安徽省芜湖市第一中学 许智磊 【摘要】 本文介绍后缀数组的基本概念、方法以及应用。 首先介绍O(nlogn)复杂度构造后缀数组的倍增算法,接着介绍了配合后缀数组的最长公共前缀 LCP(Longest Common Prefix)的计算方法,并给出一个线性时间内计算height数组(记录跨度为1的LCP值的数组)的算法。最后介绍两个应用后缀数组的例子:多模式串的模式匹配以及求最长回文子串。 【关键字】 字符串 后缀 k-前缀比较关系  后缀数组 名次数组 后缀树 倍增算法 基数排序 最长公共前缀 RMQ问题 模式匹配 回文串 最长回文子串 【正文】 在字符串处理当中,后缀树和后缀数组都是非常有力的工具,其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料。其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现,能够实现后缀树的很多功能而时间复杂度也不太逊色,并且,它比后缀树所占用的空间小很多。可以说,在信息学竞赛中后缀数组比后缀树要更为实用。因此在本文中笔者想介绍一下后缀数组的基本概念、构造方法,以及配合后缀数组的最长公共前缀数组的构造方法,最后结合一些例子谈谈后缀数组的应用。 基本概念 首先明确一些必要的定义: 字符集  一个字符集Σ是一个建立了全序关系的集合,也就是说,Σ中的任意两个不同的元素α和β都可以比较大小,要么αβ,要么βα(也就是αβ)。字符集Σ中的元素称为字符。 字符串  一个字符串S是将n个字符顺次排列形成的数组,n称为S的长度,表示为len(S)。S的第i个字符表示为S[i]。 子串   字符串S的子串S[i..j],i≤j,表示S串中从i到j这一段,也就是顺次排列S[i],S[i+1],...,S[j]形成的字符串。 后缀   后缀是指从某个位置i开始到整个串末尾结束的一个特殊子串。字符串S的从i开头的后缀表示为Suffix(S,i),也就是Suffix(S,i)=S[i..len(S)]。 关于字符串的大小比较,是指通常所说的“字典顺序”比较,也就是对于两个字符串u、v,令i从1开始顺次比较u[i]和v[i],如果相等则令i加1,否则若u[i]v[i]则认为uv,u[i]v[i]则认为uv(也就是vu),比较结束。如果ilen(u)或者ilen(v)仍比较出结果,那么若len(u)len(v)则认为uv,若len(u)=len(v)则认为u=v,若len(u)len(v)则uv。 从字符串的大小比较的定义来看,S的两个开头位置不同的后缀u和v进行比较的结果不可能是相等,因为u=v的必要条件len(u)=len(v)在这里不可能满足。 下面我们约定一个字符集Σ和一个字符串S,设len(S)=n,且S[n]=$,也就是说S以一个特殊字符$结尾,并且$小于Σ中的任何一个字符。除了S[n]之外,S中的其他字符都属于Σ。对于约定的字符串S,从位置i开头的后缀直接写成Suffix(i),省去参数S。 后缀数组 后缀数组SA是一个一维数组,它保存1..n的某个排列SA[1],SA[2],...SA[n],并且保证 Suffix(SA[i])Suffix(SA[i+1]),1≤in。也就是将S的n个后缀从小到大进行排序之后把排好序的后缀的开头位置顺次放入SA中。 名次数组 名次数组Rank=SA-1,也就是说若SA[i]=j,则Rank[j]=i,不难看出Rank[i]保存的是Suffix(i)在所有后缀中从小到大排列的“名次”。 构造方法 如何构造后缀数组呢?最直接最简单的方法当然是把S的后缀都看作一些普通的字符串,按照一般字符串排序的方法对它们从小到大进行排序。 不难看出,这种做法是很笨拙的,因为它没有利用到各个后缀之间的有机联系,所以它的效率不可能很高。即使采用字符串排序中比较高效的Multi-key Quick Sort,最坏情况的时间复杂度仍然是O(n2)的,不能满足我们的需要。 下面介绍倍增算法(Doubling Algorithm),它正是充分利用了各个后缀之间的联系,将构造后缀数组的最坏时间复杂度成功降至O(nlogn)。 对一个字符串u,我们定义u的k-前缀 定义k-前缀比较关系k、=k和≤k: 设两个字符串u和v, ukv 当且仅当 ukvk u=kv 当且仅当 uk=vk u≤kv 当且仅当 uk≤vk 直观地看这些加了一个下标k的比较符号的意义就是对两个字符串的前k个字符进行字典序比较,特别的一点就是在作大于和小于的比较时如果某个字符串的长度不到k也没有关系,只要能够在k个字符比较结束之前得到第一个字符串大于或者小于第二个字符串就可以了。 根据前缀比较符的性质我们可以得到以下的非常重要的性质: 性质1.1 对k≥n,Suffix(i)kSuffix(j)

文档评论(0)

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

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

1亿VIP精品文档

相关文档