可以看到,相邻的后缀之间可能有一些共同前缀。 我们令 height[i]=\mathrm{lcp}(sa[i],sa[i-1]) ,其中 \mathrm{lcp} 表示最长公共前缀。利用这个 height 数组,我们可以做很多事。 例如,我们可以按字典序遍历所有本质不同的子串。只需要遍历 sa[i] 的前缀,但是跳过前 height[i] 个,因为这 height[i] 个...
到目前为止,我们在本章中看到的算法可以有效地找到文本中出现的所有模式,然而,这些算法没法做到更多。本节介绍了另一种方法——后缀数组,通过使用它你不仅可以找到文本中出现的所有模式,还可以找到更多。后缀数组不会像 Knuth-Morris-Pratt 算法那样能够快速地找到模式的所有出现位置,但它具有更多的灵活性,因此非常值得...
后缀数组算法介绍 简介:后缀数组学习 1.后缀:后缀指的是从字符串的某个位置i到字符串末尾的子串,我们定义以s的第i个字符为第一个元素的后缀为suff(i)。 2.后缀数组sa[i]表示排名为i的后缀的起始位置的下标。 3.ran(i)表示起始位置的下标为i的后缀排名。 4.LCP(i,j)表示suff(sa[i])与suff(sa[j])的...
1importjava.util.Arrays;23publicclassSuffixArray {4publicstaticvoidmain(String[] args) {5match();//得到结果是56}78staticvoidmatch(){9String s = "ABABABABB";10String p = "BABB";11//SuffixArray.Suff[] sa = SuffixArray.getSa(s);//后缀数组12Suff[] sa = getSa2(s);//后缀数组13intl...
*@return*/publicstaticSuff[] getSa(String src){intstrLength =src.length();//sa 即SuffixArray,后缀数组//sa 是排名到下标的映射,即sa[i]=k说明排名为i的后缀是从k开始的Suff[] suffixArray =newSuff[strLength];for(inti = 0; i < strLength; i++) { ...
利用倍增算法得到suffix[i]的有序数组Rank[i]之后,就可以分别在O(N)的时间复杂度内得到SA[i]数组和H[i]数组; 后缀数组的应用: 最长公共前缀(LCP,Longest Common Prefix)的后缀数组解法:构建SA[i]数组中相邻元素的最长公共前缀(LCP,Longest Common Prefix),Height[i]表示SA[i]和SA[i-1]的...
一、后缀数组的实现 本节主要介绍后缀数组的两种实现方法:倍增算法(Doubling Algorithm)和DC3算法(Difference Cover),并对两种算法进行了比较。可能有的读者会认为这两种算法难以理解,即使理解了也难以用程序实现。本节针对这个问题,在介绍这两种算法的基础上,还给出了简洁高效的代码。其中倍增算法只有25行,DC3算法只有...
字符串匹配(三)---后缀数组算法 ⼀、什么是后缀数组: 字符串后缀Suffix指的是从字符串的某个位置开始到其末尾的字符串⼦串。后缀数组 Suffix Array(sa)指的是将某个字符串的所有后缀按字典序排序之后得到的数组,不过数组中不直接保存所有的后缀⼦串,只要记录后缀的起始下标就好了。 ⽐如下⾯在...
·SA数组(后缀数组):保存所有后缀排序后从小到大的序列。[即SA[i]=j表示排名第i的后缀编号为j] ·rank数组(名次数组):记录后缀的名次。[即rank[i]=j表示编号为i的后缀排名第j] 用倍增算法可以在O(nlogn)时间内得出这两个数组。 具体过程如下:
DC3算法 (1)将所有的后缀分成两部分,一部分是模3不等于0的,比如Suffix[1],Suffix[2],Suffix[4],Suffix[7]等,第二部分是模3等于0的后缀,Suffix[0],Suffix[3]等。首先计算第一部分每个后缀的排名(计算的时候假设没有第二部分的这些后缀)。方法是将Suffix[1]和Suffix[2]连起来( 连起来之前要把Suffix[1...