字尾陣列之最長公共字首

2021-12-29 23:38:31 字數 1519 閱讀 6721

#include

#define maxn 100

int main()

,s[maxn]= ;//s串可以看成abcbc

int i,j,k=0;

for(i=0; i<5; i++)

rank[sa[i]]=i;

for(i=0; i<5; i++)

if(k)

k--;

j=sa[rank[i]-1];

/*當rank[k]不等於0的時候,rank[i]-1計算出的是上乙個排名,通過sa陣列找出上乙個排名的起始座標

*/printf("%d %d %d\n",rank[i],i,j);

while(s[i+k]==s[j+k])

k++;

/*仔細體會i和j的關係還有字尾i控制的字元的個數

上面的while迴圈其實是當k=0的時候才進行的當排完循序後字尾k和字尾i-1相鄰即(排在字尾i-1的前乙個的是字尾k),字尾k

和字尾i-1分別刪除首字元之後得到字尾k+1和字尾i,因此字尾k+1一定排在字尾i的前面(相鄰),並且最長公共字首長度為字尾k和

字尾k和字尾i-1的最長公共字首-1即h[i-1]-1舉個例子:

字串abcbc的字尾為:

0 abcbc

1 bcbc

2 cbc

3 bc

4 c

排完序後為

0 abcbc

3 bc

1 bcbc

4 c

2 cbc

當i等於0的時候rank[0]所以height[0]等於0,k=0

當i等於1的時候rank[1]為2,rank[1]-1==1,這個時候比較的是bcbc和排在他前面的字尾bc(i控制的bcbc的下標,j控制的bc的下標),經過while()迴圈

判斷出來的是k=2即最長公共字首為2

當i等於2的時候rank[2]為4,rank[2]-1==3,這個時候比較的是cbc和排在他前面的字尾c(bcbc和bc都是由i等於1的兩個字尾都去掉乙個b之後得到的,

這個時候我們就沒有必要再去計算了,我們可以直接通過bcbc和bc的最長公共字首k減去1得到而沒必要在去計算了)

當i等於3的時候rank[3]為1,rank[1]-1==0,這個時候比較的是bc和排在他前面的字尾abcbc經過while()迴圈判斷最長公共字首為0

當i等於4的時候rank[4]為3,rank[4]-1==2,這個時候比較的是c和排在他前面的字尾bc經過while()迴圈判斷最長公共字首為0

有上述可以總結出當i是由0-n-1所以字尾是由長到短的,又因為當兩個串排好序後相鄰的時候,都去掉前面的乙個後還是相鄰的所以我們可以有長的

遞推出短的

*/height[rank[i]]=k;

}for(i=0; i<5; i++)

printf("%d ",height[i]);

puts("");

return 0;

}

字尾陣列 LCP(最長公共字首)

sa sa陣列儲存的是乙個1 n的全排列,儲存的是 將所有字尾按字典序排序後,串在原串中的位置。即有suffix sa i suffix sa i 1 rank rank陣列儲存的是 suffix i 在所有字尾中按字典序排序的 名次 總結 字尾陣列是 排第幾的是誰?名次陣列是 你排第幾?lcp i...

LeetCode之最長公共字首

近期開始為了找實習開始刷leetcode,吃了大學不好好鍛鍊寫 能力虧的,現在一邊刷,一邊記錄下。最長公共字首就是給定字串陣列,讓輸出最長的公共字首。最長公共字首不會比陣列中的最短的字串長,首先將該陣列中的第乙個字串作為起始的最短字串,然後與後面的字串進行比較,然後變換最短字串。再進行字元的比較,選...

力扣之最長公共字首

編寫乙個函式來查詢字串陣列中的最長公共字首。如果不存在公共字首,返回空字串 我的思路是取陣列第一項為最初的值,然後和其他的各項進行,比較,然後得出公共字首。var longestcommonprefix function strs else common common.substr 0,j if c...