#sa[i]表示排名為i的字尾的起始字元下標為sa[i]
def build_sa(s,n,m, c, sa, x, y):
for i in range(0,n):
x[i] = s[i]
c[ord(x[i])] += 1
for i in range(1,m):
c[i] += c[i-1]
for i in range(n-1, -1, -1):
c[ord(x[i])] -= 1
sa[c[ord(x[i])]] = i
k = 1
while k <= n:
p = 0
for i in range(n-k,n):
y[p] = i
p += 1
for i in range(0,n):
if sa[i] >= k:
y[p] = sa[i] - k
p += 1
for i in range(0,m):
c[i] = 0
if k == 1:
for i in range(0, n):
c[ord(x[y[i]])] += 1
for i in range(1, m):
c[i] += c[i - 1]
for i in range(n - 1, -1, -1):
c[ord(x[y[i]])] -= 1
sa[c[ord(x[y[i]])]] = y[i]
else:
for i in range(0, n):
c[x[y[i]]] += 1 #當k大於1時,因為x中元素全為整數,不再是ascil碼,所以不能在使用ord
for i in range(1, m):
c[i] += c[i - 1]
for i in range(n - 1, -1, -1):
c[x[y[i]]] -= 1
sa[c[x[y[i]]]] = y[i]
x,y = y,x
p = 1
x[sa[0]] = 0
for i in range(1,n):
if y[sa[i-1]] == y[sa[i]] and y[sa[i-1]+k] == y[sa[i]+k]:
x[sa[i]] = p - 1
else:
x[sa[i]] = p
p += 1
if p >= n:
break
m = p
k = k * 2
return
def get_suffix(s):
m = 128 # 128個ascil
n = len(s)
maxn = 1000 # 字串的最大長度
c = [0] * maxn
sa = [0] * maxn
x = [0] * maxn
y = [0] * maxn
suffix = [""] * n
build_sa(s, n, m, c, sa, x, y)
for i in range(0, n):
suffix[i] = s[sa[i]:] # suffix中儲存的就是排序後的字尾陣列
return suffix
if __name__ == "__main__":
s = "aabaaaab"
suffix = get_suffix(s)
print(suffix)
字尾陣列的基數排序實現
注 不懂基數排序的看這裡 基數排序 基數排序的時間複雜度是 題目 落谷p3809 模板 字尾陣列 c 實現 include using namespace std define infy 0x3f3f3f3f define lowbit x x x define e exp 1 define pi ...
Codevs 1500 字尾排序 字尾陣列
1500 字尾排序 時間限制 1 s 空間限制 128000 kb 題目等級 大師 master 題目描述 description 天凱是mit的新生。prof.handsomeg給了他乙個長度為n的由小寫字母構成的字串,要求他把該字串的n個字尾 suffix 從小到大排序。何謂字尾?假設字串是s ...
Uoj 35 字尾排序 字尾陣列
統計 描述 提交 自定義測試 這是一道模板題。讀入乙個長度為 nn 的由小寫英文本母組成的字串,請把這個字串的所有非空字尾按字典序從小到大排序,然後按順序輸出字尾的第乙個字元在原串中的位置。位置編號為 11 到 nn。除此之外為了進一步證明你確實有給字尾排序的超能力,請另外輸出 n 1n 1 個整數...