一、什麼是Lyndon
Lyndon是一種特殊的字元串,它是指任意長度字元串的最小循環移位,也就是將原字元串旋轉任意個字元所得到的所有字元串中,字典序最小的字元串。Lyndon串在密碼學中有很多應用,有些經典密碼學演算法就是基於Lyndon串的,而且它在字元串演算法中廣泛應用,比如字元串匹配等。
舉個例子,比如要把ababab做旋轉,可以得到6個結果:ababab、bababa、ababab、bababa、ababab、bababa。把這6個字元串排個序,可以得到6個字元串:ababab、ababab、ababab、bababa、bababa、bababa。而我們需要找到其中的Lyndon串,也就是字典序最小的字元串,即ababab。
二、Lyndon串的性質
Lyndon串有一些特別的性質,下面我們來介紹一下。
1、Lyndon串是原串的循環移位中字典序最小的串。
2、Lyndon串不能被更小的Lyndon串的循環移位所表示。
3、任意一個字元串都可以表示為若干個Lyndon串的連接,這些Lyndon串可以按字典序排列。
4、一個串是Lyndon串的充要條件是它本身小於所有非平凡循環移位的最小值。
這些性質可以用來做一些有趣的事情,比如求一個長字元串中最短的Lyndon串,或者求Lyndon串的個數等。
三、Lyndon分解
根據Lyndon串的性質,我們可以將任意一個字元串進行分解,使得每個分解部分都是一個Lyndon串。
def lyndon_decompo(s):
"""
對字元串s進行Lyndon分解
"""
res = []
i = 0
while i < len(s):
j, k = i, i + 1
while k < len(s) and s[j] <= s[k]:
if s[j] < s[k]:
j = i
else:
j += 1
k += 1
while i <= j:
res.append(s[i: i + k - j])
i += k - j
return res
上面的代碼中,我們從i開始,找到一個比s[i]大的位置k,然後從j開始找到一個位置,使得從j到k的所有子串都不是Lyndon串。這樣得到一個Lyndon分解,時間複雜度是O(N)。
四、Lyndon串的應用
Lyndon串在字元串演算法中有很多應用,這裡列舉兩個常見的應用:字元串匹配和Lyndon串的個數。
五、字元串匹配
字元串匹配是一個比較經典的問題,主要是檢查文本串中是否有一個模式串出現。我們可以用暴力演算法或者KMP演算法等來解決這個問題,下面我們介紹一種基於Lyndon串的字元串匹配演算法。
def lyndon_search(s, pattern):
"""
基於Lyndon串的字元串匹配演算法
"""
def solve(A, pattern):
if not A:
return False
if A[0] == pattern:
return True
if A[0] > pattern:
return False
# 對每個前綴進行繼續分解
for i in range(1, len(A)):
if solve(A[:i], pattern) and solve(A[i:], pattern):
return True
return False
# 將s分解為Lyndon串列表
A = lyndon_decompo(s)
# 遞歸地尋找pattern
return solve(A, pattern)
上面的代碼中,我們將文本串s進行Lyndon分解,然後遞歸地尋找模式串pattern是否在Lyndon分解列表中出現。這個演算法的時間複雜度主要取決於Lyndon分解的時間複雜度,最壞情況下是O(N ^ 2)。
六、Lyndon串的個數
我們可以用dp方法來求解n長度字元串中的Lyndon串數量,下面給出代碼實現。
def count_lyndon(n):
"""
求n長度字元串中的Lyndon串數量
"""
dp = [1] * (n + 1)
for i in range(1, n + 1):
for j in range(i // 2, 0, -1):
dp[i] += dp[j]
return dp[n]
上面的代碼中,我們用dp[i]表示長度為i的字元串中的Lyndon串數量。對於任意一個i,我們可以將其分成兩個長度為j和長度為i-j的子串。如果這兩個子串不等,那麼dp[i]就可以加上dp[j]。這樣我們可以遞推得到所有的dp[i]。
七、小結
通過本文的介紹,我們了解了Lyndon串的概念、性質、分解以及應用。Lyndon串在密碼學、字元串演算法中都有廣泛的應用,對於演算法開發工程師來說,了解Lyndon串的概念和性質可以給我們帶來很多啟示。而代碼實現方面,我們介紹了Lyndon分解、字元串匹配和求Lyndon串數量等演算法的實現方法。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/183069.html
微信掃一掃
支付寶掃一掃