#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...