后綴樹/后綴數組

字典樹:https://blog.csdn.net/hebtu666/article/details/83141560

后綴樹:后綴樹,就是把一串字符的所有后綴保存并且壓縮的字典樹。

?

相對于字典樹來說,后綴樹并不是針對大量字符串的,而是針對一個或幾個字符串來解決問題。比如字符串的回文子串,兩個字符串的最長公共子串等等。

比如單詞banana,它的所有后綴顯示到下面的。0代表從第一個字符為起點,終點不用說都是字符串的末尾。

以上面的后綴,我們建立一顆后綴樹。如下圖,為了方便看到后綴,我沒有合并相同的前綴。

把非公共部分壓縮:

后綴樹的應用:

(1)查找某個字符串s1是否在另外一個字符串s2中:如果s1在字符串s2中,那么s1必定是s2中某個后綴串的前綴。

(2)指定字符串s1在字符串s2中重復的次數:比如說banana是s1,an是s2,那么計算an出現的次數實際上就是看an是幾個后綴串的前綴。

(3)兩個字符串S1,S2的最長公共部分(廣義后綴樹)

(4)最長回文串(廣義后綴樹)

?

關于后綴樹的實現和應用以后再寫,這次主要寫后綴數組。

在字符串處理當中,后綴樹和后綴數組都是非常有力的工具。其實后綴數組是后綴樹的一個非常精巧的替代品,它比后綴樹容易編程實現,能夠實現后綴樹的很多功能而時間復雜度也不太遜色,并且,它比后綴樹所占用的空間小很多。可以說,在信息學競賽中后綴數組比后綴樹要更為實用。

?

后綴數組:就是把某個字符串的所有后綴按照字典序排序后的數組。(數組中保存起始位置就好了,結束位置一定是最后)

先說如何計算后綴數組:

倍增的思想,我們先把每個長度為2的子串排序,再利用結果把每個長度為4的字串排序,再利用結果排序長度為8的子串。。。直到長度大于等于串長。

設置sa[]數組來記錄排名:sa[i]代表排第i名的是第幾個串。

結果用rank[]數組返回,rank[i]記錄的是起始位置為第i個字符的后綴排名第幾小。

我們開始執行過程:

比如字符串abracadabra

長度為2的排名:a ab ab ac ad br br ca da ra ra,他們分別排第0,1,2,2,3,4,5,5,6,7,8,8名

sa數組就是11(空串),10(a),0(ab),7,3,5,1,8,4,6,2,9(ra排名最后)

這樣,所有長度為2的子串的排名就出來了,我們如何利用排名把長度為4的排名搞出來呢?

abracadabra中,ab,br,ra這些串排名知道了。我們把他們兩兩合并為長度為4的串,進行排名。

比如abra和brac怎么比較呢?

用原來排名的數對來表示

abra=ab+ra=1+8

brac=br+ac=4+2

對于字符串的字典序,這個例子比1和4就比出來了。

如果第一個數一樣,也就是前兩個字符一樣,那再比后面就可以了。

簡單說就是先比前一半字符的排名,再比后一半的排名。

具體實現,我們可以用系統sort,傳一個比較器就好了。

?

還有需要注意,長度不可能那么湊巧是2^n,所以 一般的,k=n時,rank[i]表示從位置i開始向后n個字符的排名第幾小,而剩下不足看個字符,rank[i]代表從第i個字符到最后的串的排名第幾小,也就是后綴。

保證了每一個后綴都能正確表示并排序。比如k=4時,就表示出了長度為1,2,3的后綴:a,ra,bra.這就保證了k=8時,長度為5,6,7的后綴也能被表示出來:4+1,4+2,4+3

還有,sa[0]永遠是空串,空串的排名rank[sa[0]]永遠是最大。

int n;
int k;
int rank[MAX_N+1];//結果(排名)數組
int tmp[MAX_N+1];//臨時數組
//定義比較器
bool compare(int i,int j)
{if(rank[i]!=rank[j])return rank[i]<rank[j];//長度為k的子串的比較int ri=i+k<=n ? rank[i+k] : -1;int rj=j+k<=n ? rank[j+k] : -1;return ri<rj;
}void solve(string s,int *sa)
{n=s.length;//長度為1時,按字符碼即可,長度為2時就可以直接用for(int i=0;i<=n;i++){sa[i]=i;rank[i]=i<n ? s[i] : -1;//注意空串為最大}//由k對2k排序,直到超范圍for(k=1;k<=n;k*=2){sort(sa,sa+n+1,compare);tmp[sa[0]=0;//空串for(int i=1;i<=n;i++){tmp[sa[i]]=tmp[sa[i-1]]+(compare(sa[i-1],sa[i]) ? 1 : 0);//注意有相同的}for(int i=0;i<=n;i++){rank[i]=tmp[i];}}
}

具體應用以后再寫。。。。。

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445515.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445515.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445515.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

kaggle(02)-房價預測案例(基礎版)

房價預測案例 Step 1: 檢視源數據集 import numpy as np import pandas as pd讀入數據 一般來說源數據的index那一欄沒什么用&#xff0c;我們可以用來作為我們pandas dataframe的index。這樣之后要是檢索起來也省事兒。 有人的地方就有鄙視鏈。跟知乎一樣。Kaggle的也是個處…

為什么Python中整型不會溢出

前言 本次分析基于 CPython 解釋器&#xff0c;python3.x版本 在python2時代&#xff0c;整型有 int 類型和 long 長整型&#xff0c;長整型不存在溢出問題&#xff0c;即可以存放任意大小的整數。在python3后&#xff0c;統一使用了長整型。這也是吸引科研人員的一部分了&am…

如何使用github中的pull request功能?

* pull request是社會化編程的象征&#xff0c;通過這個功能&#xff0c;你可以參與到別人開發的項目中&#xff0c;并做出自己的貢獻。pull request是自己修改源代碼后&#xff0c;請求對方倉庫采納的一種行為*–《github入門與實踐》 下面具體說一下github中使用pull reque…

「假裝努力」

有多少人在「假裝努力」&#xff1f; 又有多少人在「真正成長」&#xff1f; 再努力努力 回想起當年畢業后&#xff0c;在北京和室友合租的日子。 那時&#xff0c;我在工作&#xff0c;室友在培訓。 一天&#xff0c;我下班回來&#xff0c;聽見他在電話里和家人爭吵&…

如何閱讀論文?

本文主要講述了如何才能高效的閱讀一篇論文&#xff01;&#xff01;

貪吃蛇js

python都學不懂&#xff0c;c又不會&#xff0c;只能寫寫js來維持生活了。555555 js&#xff1a; window.onload function() {var wrap document.getElementsByClassName("wrap")[0];var uls document.getElementsByClassName("sbody")[0];var hand …

Android studio安裝過程中入的坑的記錄與記錄

Android studio安裝過程中入的坑的記錄與記錄 * 由于最近項目的需求&#xff0c;所以最近一直在配置安卓的開發環境&#xff0c;之前用的是Eclipse ADT的模式開發的&#xff0c;配置環境也花了一些時間&#xff0c;但是由于谷歌大力扶持它的親兒子Android Studio&#xff0c;…

動態規劃基礎水題提綱

提綱 漢諾塔 漢諾塔&#xff1a;漢諾塔&#xff08;又稱河內塔&#xff09;問題是源于印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子&#xff0c;在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新…

數據結構課上筆記8

串的概念&#xff1a;串&#xff08;字符串&#xff09;&#xff1a;是由 0 個或多個字符組成的有限序列。 通常記為&#xff1a;s ‘ a1 a2 a3 … ai …an ’ ( n≥0 )。 串的邏輯結構和線性表極為相似。 一些串的類型&#xff1a; 空串&#xff1a;不含任何字符的串&#x…

數據結構課上筆記9

數組&#xff1a;按一定格式排列起來的具有相同類型的數據元素的集合。 二維數組&#xff1a;若一維數組中的數據元素又是一維數組結構&#xff0c;則稱為二維數組。 同理&#xff0c;推廣到多維數組。若 n -1 維數組中的元素又是一個一維數組結構&#xff0c;則稱作 n 維數組…

pySerial -- Python的串口通訊模塊

pySerial Overview This module encapsulates the access for the serial port. It provides backends for Python running on Windows, Linux, BSD (possibly any POSIX compliant system), Jython and IronPython (.NET and Mono). The module named “serial” automatica…

串的堆分配實現

今天&#xff0c;線性結構基本就這樣了&#xff0c;以后&#xff08;至少是最近&#xff09;就很少寫線性基礎結構的實現了。 串的類型定義 typedef struct {char *str;int length; }HeapString; 初始化串 InitString(HeapString *S) {S->length0;S->str\0; } 長度 …

Numpy 入門

Numpy 入門 Numpy簡介 官網鏈接&#xff1a;http://www.numpy.org/NumPy是Python語言的一個擴充程序庫。支持高級大量的維度數組與矩陣運算&#xff0c;此外也針對數組運算提供大量的數學函數庫 Numpy的基本功能 快速高效的多維數組對象ndarray用于對數組執行元素級計算以…

數據結構課上筆記10

樹 樹的定義&#xff1a;樹(Tree)是 n(n≥0)個結點的有限集。若 n0&#xff0c;稱為空樹&#xff1b;若 n > 0&#xff0c;則它滿足如下兩個條件&#xff1a; (1) 有且僅有一個特定的稱為根 (Root) 的結點&#xff1b; (2) 其余結點可分為 m (m≥0) 個互不相交的有限…

pandasStudyNoteBook

pandas 入門培訓 pandas簡介 - 官網鏈接&#xff1a;http://pandas.pydata.org/ - pandas pannel data data analysis - Pandas是python的一個數據分析包 , Pandas最初被作為金融數據分析工具而開發出來&#xff0c;因此&#xff0c;pandas為時間序列分析提供了很好的支持 …

最大搜索子樹

給定一個二叉樹的頭結點&#xff0c;返回最大搜索子樹的大小。 我們先定義結點&#xff1a; public static class Node {public int value;public Node left;public Node right;public Node(int data) {this.value data;}} 分析&#xff1a; 直接判斷每個節點左邊小右邊大是…

二叉樹最長路徑

分析&#xff1a; 暴力求每一段距離也可。 對于以本節點為根的二叉樹&#xff0c;最遠距離有三種可能&#xff1a; 1&#xff09;最遠路徑來自左子樹 2 &#xff09;最遠路徑來自右子樹&#xff08;圖示與左子樹同理&#xff09; 3&#xff09;最遠路徑為左右子樹距離根最遠…

判斷完全二叉樹

完全二叉樹的定義: 一棵二叉樹&#xff0c;除了最后一層之外都是完全填充的&#xff0c;并且最后一層的葉子結點都在左邊。 https://baike.baidu.com/item/%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%8F%89%E6%A0%91/7773232?fraladdin 百度定義 思路&#xff1a;層序遍歷二叉樹 如果…

判斷二叉搜索樹

二叉查找樹&#xff08;Binary Search Tree&#xff09;&#xff0c;&#xff08;又&#xff1a;二叉搜索樹&#xff0c;二叉排序樹&#xff09;它或者是一棵空樹&#xff0c;或者是具有下列性質的二叉樹&#xff1a; 若它的左子樹不空&#xff0c;則左子樹上所有結點的值均小于…

劍指offer_01

文章目錄[toc]第一章 面試流程1.1 面試官談面試1.2 面試3種形式1.3 面試的3個環節第一章 面試流程 1.1 面試官談面試 初級的程序員談算法和數據結構&#xff0c;高級的程序員談項目經驗要對公司近況和項目情況了解不要緊張&#xff0c;不要馬上上手寫代碼 1.2 面試3種形式 …