- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
后缀数组的定义及实现
后缀数组的定义及实现
1 后缀数组的定义
1.1 后缀数组的相关概念
(1) 文本串的后缀:对于符号表Σ上的长度为n的文本串T[1...n],文字串T的后缀是指从第i个字符开始到T的末尾所形成的子串T[i...n],1 ≤ i ≤ n。
(2) 子串:在长度为 n的文字串T中,下标从i到j的连续的(j-i+1)个字符所组成的字符序列就是文字串T的一个长度为( j – i + 1)子串,其中1 ≤ i ≤ j ≤ n。
(3) 后缀数组:后缀数组SA是T的所有后缀T0, T1, ... Tn-1的一个字典序排序,即SA[i] = j表示后缀Tj是字符串集合{T0, T1, ... Tn-1}中第i个最小字符串。排序后的后缀数组具有如下性质:
TSA[0] TSA[1] … TSA[n - 1]
下图为后缀数组及其名次示例(T = acaaccg$)
此图表示描述了了SA中所需要得到的SA[i]和Rank[i],其中Rank[i] = j表示T中的第i个后缀在所有后缀的字典排名为j。
SA[i] = j的两种表示理解方式:(1) 表示Tj在字符串集合中排名为i (2) 表示排名为i的后缀的Position。
1.2 后缀数组的相关数组解释
为了理解后缀数组,我们需要理解以下两个数组的含义以及它们之间的相互关系:
SA数组(Pos数组):SA数组是我们需要直接使用的数组,SA数组是FM-index的基础,后面的bwt正是在SA的基础上进行变化得到文本L。在1.1中提到:SA[i] = j表示后缀Tj是字符串集合{T0, T1, ... Tn-1}中第i个最小字符串。因此SA[i] = j的两种表示理解方式:(1)表示Tj在字符串集合中排名(字典序排名)为i。(2)表示排名为i的后缀的Position。
Rank数组:Rank数组是后缀数组的逆数组SA-1,即若SA[j] = i,则Rank[i] = j,其实质反映了T中的第i个后缀在所有后缀中的字典序排名为j。
2 倍增法后缀数组
2.1 倍增法后缀数组基本概念
倍增法可以在logn步完成后缀数组的构造,n代表字符串A的长度。在倍增过程中,要维护两个整型、大小为N的数组Pos,Rank。Pos [i] 表示排名为i的后缀的Position,即在原字符串中的起始位置。Rank[i]表示在原字符串i处开始的后缀的排名,明显Pos[Rank[i]]=i。在第一阶段,所有后缀按首字母进行桶排序,即:所有首字母相同的后缀位于同一个桶内,且桶与桶之间按字典序排序。
之后,每个阶段按照2倍于上次的字符数参与新一轮的桶排序。明显在k阶段,参与比较的字符数为2K个,用H表示,即所有前H个字符相同的后缀处于同一个桶内。现在假设H阶段已经排序完成,即Pos数组,Rank数组有正确的值,倍增算法的基本思路是:根据H阶段的Pos值,Rank值, 构造2H阶段的Pos值,Rank值。
假设Ai和Aj是H阶段同一个桶内的两个后缀,这意味着:Ai和Aj的前H个字符是相同的,接下来需要比较后续的H个字符,即H+1到2H之间的字符。非常巧的是,这H个需要比较的字符也恰巧是后缀Ai+H,Aj+H的前H个字符,假设我们已经知道Ai+H,Aj+H按≤H的字典序关系(≤H的字典序表示后缀间按前H个字符的大小关系得到的字典序,后续的≤H,≤2H意义相同),则:
从第一个桶的最左边(按≤H字典序最小)的后缀开始扫描,得到第一个后缀Ai,很明显Ai的前H个字符是最小的,考虑后缀Ai-H,其H到2H阶段的H个字符是最小的(Ai的前H个字符是最小的),所以Ai-H 这个后缀应该处在它所在2H阶段的相应桶内的最左端(最小)。所以,算法的整体思路就是:扫描H阶段按≤H有序的桶内的所有后缀,对于每一个后缀Ai,将Ai-H 移动到它的桶内的下一个位置。当H阶段的扫描完成时,所有后缀都已经按≤2H的顺序处于对应的桶内,同一个桶内的所有后缀的前2H个字符都是相同的。在这个过程中,我们也需要维护一个BH数组,用来表示桶的边界,大小为n,初始值为全0,在每个桶的起始位置处为1,所以在BH数组中,假设两个连续的1对应的下标为S,V,则排名在[S,V?1]之间的所有后缀处在同一个桶内。
伴随着H的增大,旧桶破裂,新桶产生,且桶的数目在增大(此过程对应BH数组的变化),在最后一个阶段,桶的数目等于N,BH数组全为1,此时每个桶里只有一个后缀,排序完成。所以算法的大致流程为:
1:所有后缀按首字母桶排序,得到对应的Pos,Rank,BH数组。
2:在已有H阶段Pos,Rank,BH数据的情况下,按≤H的顺序扫描所有桶内的所有后缀Ai,移动Ai-H 到对应位置(实质是修改Rank的值)。最终得到≤2H阶段的Pos,Rank,BH
文档评论(0)