字串迴圈同構的最小表示法

2021-06-04 03:02:46 字數 1335 閱讀 4111

迴圈字串的最小表示法的問題可以這樣描述:

對於乙個字串s,求s的迴圈的同構字串s』中字典序最小的乙個。

由於語言能力有限,還是用實際例子來解釋比較容易:

設s=bcad,且s』是s的迴圈同構的串。s』可以是bcad或者cadb,adbc,dbca。而且最小表示的s』是adbc。

對於字串迴圈同構的最小表示法,其問題實質是求s串的乙個位置,從這個位置開始迴圈輸出s,得到的s』字典序最小。

一種樸素的方法是設計i,j兩個指標。其中i指向最小表示的位置,j作為比較指標。

令i=0,j=1

如果s[i] > s[j] i=j, j=i+1

如果s[i] < s[j] j++

如果s[i]==s[j] 設指標k,分別從i和j位置向下比較,直到s[i] != s[j]

如果s[i+k] > s[j+k] i=j,j=i+1

否則j++

返回i起初,我想在j指標後移的過程中加入乙個優化。就是j每次不是加1,而是移動到l位置。其中,l>j且s[l]<=s[j]。但是,即使加入這一優化,在遇到bbb…bbbbbba這樣的字串時複雜度將退化到o(n^2)。

注意到,樸素演算法的缺陷在於斜體的情況下i指標的移動太少了。針對這一問題改進就得到了最小表示法的演算法。最小表示法的演算法思路是維護兩個指標i,j。

令i=0,j=1

如果s[i] > s[j] i=j, j=i+1

如果s[i] < s[j] j++

如果s[i]==s[j] 設指標k,分別從i和j位置向下比較,直到s[i] != s[j]

如果s[i+k] > s[j+k] i=i+k

否則j++

返回i和j的小者

注意到上面兩個演算法唯一的區別是粗體的一行。這一行就把複雜度降到o(n)了。

值得一提的是,與kmp類似,最小表示法處理的是乙個字串s的性質,而不是看**時給人感覺的處理兩個字串。

應用最小表示法判斷兩個字串同構,只要將兩個串的最小表示求出來,然後從最小表示開始比較。剩下的工作就不用多說了。

int minrp(char *s, int l)

}return i;

}

附poj 1509模板,跟zoj 1729差不多

#define n 10005

char str[n];

int minrp(char *s,int l)

}return i;

}int main()

return 0;

}

最小表示法 字串迴圈同構問題

用最小表示法返回最小表示串 字典序最小的同構串 第乙個字元在原始串中的下標。用兩個指標i,j,i初始化為0,j初始化為1,用k表示當前已經匹配串的長度。如果str i k str j k j 否則如果str i k str j k 說明以i開始的同構串肯定不是最小的,並且以i開始的到以i k開始的都...

最小表示法(迴圈同構串)

長度為n的序列,迴圈同構串中字典序最小的就是最小表示 序列 4 3 2 1 它的迴圈同構串為 3 2 1 4 2 1 4 3 1 4 3 2 其中字典序最小的就是1 4 3 2 我們最先想到的就是暴力列舉 判斷 可以對所給序列進行列舉所有的字典序,然後找出最小的字典序即可,但是我們列舉 判斷的時間複...

字串最小表示法

最小表示法的定義 給定乙個字串,不斷地把最後乙個元素移到最前面,可得有n個這樣的字串 稱這n個字串是迴圈同構的 那麼最小表示就是這n個裡面字典序最小的乙個 怎麼求最小表示 wrong 最樸素的方法,把每乙個這樣的字串求出來,然後一一比較,找到字典序最小的迴圈同構串 然後資料範圍變大肯定會超時 那麼正...