最小表示法

2021-09-24 02:21:53 字數 1700 閱讀 5667

給定乙個字串  s[1~n] , 如果我們不斷的把它的最後乙個字元放到開頭,最終會得到 n 個字串, 稱這 n 個字串是迴圈同構的。這些字串中字典序最小的稱為 字串 s 的最小表示 。

例如 "abca" ,  它的4個迴圈同構字串為 "abca" , "aabc" , "caab" , "bcaa" . s 的最小表示是 "aabc"  .因為乙個與 s 迴圈同構的字串可以用該字串在s 中的起始下標來表示,所以我們就用 b[i] 來表示 從 i 開始的迴圈同構字串 , 即 s[i~n] + s[1 ~ i-1 ]  。

如何求出乙個字串的最小表示 ? 最樸素的方法就是依次比較 這 n 個迴圈同構字串 ,找出字典序最小的乙個 . 比較兩個迴圈同構字串 b[i] 和 b[j] 時,我們採用的是直接向後掃瞄的方式. 依次取  k = 0,1 ,2 .. . ., 比較 b[i+k] 和 b[ j +k] 是否相等 ,直到找到乙個不相等的位置,從而確定出 b[i] 和 b[j] 的大小關係 . 

實際上,乙個字串的最小表示可以在o(n) 的線性時間內求出 . 我們首先把 s 字串複製乙份接在它的尾端,得到 ss. 

顯然  b[i] = ss[i ~ i+n-1 ] 從 i 開始的 n 個字元 .  

s = "bacacabc" ,i =2 , j =4 , k =3 下標1

2345

6789

1011

1213

1415

1617

ii+kba

caca

bcba

caca

bcjj+kba

caca

bcba

caca

bc如果在 i + k 與 j +k 處發現不相等 , 假設 ss[i+k]  > ss[j+k]  ,那麼當然可以知道 b[i] 不是最小表示(因為存在乙個更小的迴圈同構字串 b[j] ) .除此之外 , 我們還可以 b[i+1] , b[i+2] ... b[i+k] 也都不是最小表示,因為對於 1<=p <=k ,存在乙個比b[i+p]更小的迴圈同構串b[j+p ] , b[i+p] > b[j+p] ;

同理如果 ss[i+k ] 最小表示演算法

1   初始化 i = 1 , j = 2  ; 

2  通過直接向後掃瞄方法, 比較 b[i]  與 b[j] 兩個迴圈同構串.

(1) 如果掃瞄了 n 個字串仍然相等, 說明 s 只由一種字元構成 . 任意 b[i] 都是 它的最小表示. 

(2) 如果在 i+k 與 j + k 處發現不相等 . 

如果 ss[i+k] >ss[j+k]  令 i = i+k+1 , 若此時i = j , 則令 i = i+1 

如果 ss[ i +k] 3 如果 i > n , b[j] 為最小表示 , j > n ,b[i] 為最小表示. 否則重複第二步 

#include #include #include #include #define swap(a,b)  a ^= b ^= a ^= b

int main()

int i = 1 , j = 2 , k ;

while(i<=n & j<=n )

else

}int ans = min(i,j) ; // b[ans] 為最小表示

for(int i = ans ; i <= ans+n -1 ; i++)

return 0 ;

}

最小表示法

最小表示法就是找出字串s的的迴圈同構串中字典序最小的乙個。那麼什麼是迴圈同構串呢。是 設s bcad 且s 是s 的迴圈同構的串。s 可以是 bcad 或者cadb,adbc,dbca 即在字串s中從i 0開始,從i迴圈到字串末尾,再從頭迴圈到i,所形成的字元就是s迴圈同構串。因為這樣的同構串不止乙...

最小表示法

最小表示法 思想 在字串迴圈同構問題中的應用 摘自周源的ppt 前言 最小表示法 比起動態規劃 貪心等思想,在當今競賽中似乎並不是很常見。但是在解決判斷 同構 一類問題中卻起著重要的作用。本文即將討論字串中的同構問題,如何巧妙地運用最小表示法來解題呢,讓我們繼續一起思考吧。到底什麼是迴圈同構的字串呢...

最小表示法

最小表示法與kmp演算法一樣都可以解決字串匹配問題,但效率更高,短,作用更大。最小表示法就是乙個字串的最小字典序。怎麼求乙個字串的最小字典序呢?首先將這個字串擴充套件一倍 建設存在d陣列裡 然後我們用三個指標i 0,j 1,k 0,來尋找最小字典序的開頭字母,為了優於kmp,我們要做到o n i表示...