• 沒有找到結果。

字串

N/A
N/A
Protected

Academic year: 2022

Share "字串"

Copied!
45
0
0

加載中.... (立即查看全文)

全文

(1)

字串

課堂補充 by qazwsxedcrfvtg14

補充 by boook

(2)

Hamming distance

(3)

漢明距離 漢明距離

• 兩個等長字符串對應位置的不同字符的個數。

• 例如:

• 1011101 與

• 1001001 之間的漢明距離是 2 。

• 2143896 與

• 2233796 之間的漢明距離是 3 。

• "toned" 與

• "roses" 之間的漢明距離是 3 。

(4)

例題 - codeforces 903E 例題 - codeforces 903E

• 現在有一個母字串 p 長度為 N ,現在要使用母字串 製造出 k 個小孩字串,製造方法:

• 1. 複製出一份獨立的母字串 P

• 2. 從裡面挑出兩個 index i, j

• 3. swap(pi, pj)

• 現在給你這 K 個小孩字串,請找到隨便一個母字串。

• K <= 2500, N <= 5000, K * N <= 5000

• 小寫字母

(5)

例題 - codeforces 903E 例題 - codeforces 903E

• 每一個母字串和小孩字串的漢明距離都很小

• K * N <= 5000, N <= 5000

• O(NNK)

• 可以枚舉可能的母字串, O(K) 判斷是否符合:

• 小孩字串的結構都要一樣

• 漢明距離 = 0 -> 有字元出現兩次

• 漢明距離 = 2

(6)

Z-value

(7)

Gus eld Algorithm fi Gus eld Algorithm fi

• 又稱 Z algorithm

• 字串 S[0:N-1] 的 Z-value

• Z[i] = 最大的 k 滿足 S[0:k-1] = S[i:i+k-1]

• 拿 S 從 i 開始的後綴 跟 S 比一比,最長的共同前綴長度

• Z[0] = 0

(8)

i 0 1 2 3 4 5 6 7 8

S[i] a b a a b a a b b

Z[i] 0 0 1 5 0 1 2 0 0

(9)
(10)

觀察 觀察

• 算完 Z[0]~Z[i-1] 後,現在要計算 Z[i] ,取任一個 b < i

• S[0:Z[b]-1] = S[b:b+Z[b]-1]

• 若 b+Z[b] > i

• x = i-b

• S[x:Z[b]-1] = S[i:b+Z[b]-1]

0 Z[b] b i b+Z[b

]

x

(11)

觀察右界和 i 的關係 觀察右界和 i 的關係

0 Z[b] b i b+Z[b

] x

0 Z[b] b i b+Z[b

] x

0 Z[b] b b+Z[b i

] x

x+Z[x]

x+Z[x] i+Z[x]

(12)

實作 實作

(13)

實作 實作

(14)

跟字串匹配沒關係啊 跟字串匹配沒關係啊

• ?

• 直接捏

• 把 [ 短字串 +( 一個奇怪字元 )+ 長字串 ] 拿去求 Z-value 會怎樣呢?

(15)

複雜度分析 複雜度分析

• O(N)?

(16)

Hash

(17)

Rolling hash Rolling hash

• 又稱 RK 算法 (Robin-Karp Algorithm)

• 核心

(18)

Rolling hash - 如果 C = 10 Rolling hash - 如果 C = 10

• S = 21334531

• M = 10000000000000000000000000000000000000000000

• H(1) = 2

• H(2) = 21

• H(3) = 213

• H(4) = 2133

• H(5) = 21334

• H(6) = 213345

• H(7) = 2133453

• H(8) = 21334531

(19)

Rolling hash Rolling hash

• 假設你有一個字串,且你已經知道其 hash 值

• 下列哪些操作可以 O(1) 執行 ?

• 加一個字元在前面

• 加一個字元在後面

• 從前面刪除一個字元

• 從後面刪除一個字元

(20)

Rolling hash Rolling hash

• 可以把 Rolling hash 想像成一個前高後低三角形

• H(1) = 2

• H(2) = 21

• H(3) = 213

• H(4) = 2133

• H(5) = 21334

(21)

Rolling hash Rolling hash

• 兩個 hash 接起來

• 一個字元也可以 算是一個 hash

*

 

• S = 213

• P = 123

• H(S) = 213

• H(P) = 123

• H(S+P)

= 213 * 1000 + 123

(22)

Rolling hash Rolling hash

• 刪除前面的字元

*

 

• S = 12345

• H(S) = 12345

• 12345 – 12000

= 345

(23)

Rolling hash Rolling hash

• 刪除後面的字元

  *

 

• S = 12345

• H(S) = 12345

• (12345 – 45) / 100 = 123

• 8 / 2 != 2 / 2 (mod 6)

(24)

Rolling hash Rolling hash

• 因為這些性質

• 我們經常會預處理好字串每個前綴的 Rolling hash

(25)

Rolling hash Rolling hash

• 這樣之後就能直接算出任意一段的 hash 值

• S = 21334

• H(1) = 2

• H(2) = 21

• H(3) = 213

• H(4) = 2133

• H(5) = 21334

• H(3~4)

= H(4) – H(2) * 100 = 33

(26)

例題 - 怎麼訂 hash 值 例題 - 怎麼訂 hash 值

• 給一個矩陣大小為 N * N

• Q 次詢問兩個大小相同的子矩陣是否相同。

• N <= 5000

• Q <= 500000

• hash 可不可以推廣到二維?

(27)

二維 hash

二維 hash

(28)

例題 - zerojudge c706 例題 - zerojudge c706

HASH 的安全性 ?

• 給定 hash function 中的 C 和 M(mod)

• C = 131

• Mod = 9007199254740992

• 請找到兩個 hash value 相同的字串,長度小於 30 ?

(29)

生日悖論 生日悖論

• 一個房間要多少人,則兩個人的生日相同的機率大於 50%?

• 23 人

• 有

n

個人,每人都隨機地從

N

個特定的數中選擇出來一個數

p

n

) = 有兩個人選擇了同樣的數字。

• 這個機率有多大 ?

(30)

例題 – 怎麼訂 hash 值 例題 – 怎麼訂 hash 值

• 假設兩個字串相似的定義如下

• 如果存在一個字元的置換方式,使得兩個字串相等,則這兩個字串相似

• 例 :

• AAA=BBB

• XYX=ABA

• ABA!=AAA

• 問 1: 給你字串集 A 和字串 B , A 中有多少字串和 B 相似

?

• 問 2: 給你一個字串 C , Q 次問兩段區間是否相似 ?

• Sum(|Ai|), |A|, |B| < 10^6, C, Q <= 10^6

(31)

Suffix array

(32)

Suffix Array Suffix Array

• 現在給你一個字串,拿出他的所有後綴後,把那些後綴排序所得 到的結果就是 Suffix Array

• 例子 :

• 字串 :abacab

• 後綴 :abacab 、 bacab 、 acab 、 cab 、 ab 、 b

• 排序

• ab

• abacab

• acab

• b

• bacab

• cab

(33)

Suffix Array Suffix Array

• 怎麼做呢 ?

• 倍增法

(34)

Suffix Array Suffix Array

• a b a c a b a d

• 1 2 1 3 1 2 1 4

• a b a c a b a d

• 12 21 13 31 12 21 14 40

• a b a c a b a d

• 1 4 2 5 1 4 3 6

(35)

Suffix Array Suffix Array

• a b a c a b a d

• 1 4 2 5 1 4 3 6

• a b a c a b a d

• 12 45 21 54 13 46 30 60

• a b a c a b a d

• 1 5 3 7 2 6 4 8

(36)

Suffix Array Suffix Array

• a b a c a b a d

• 1 5 3 7 2 6 4 8

• a b a c a b a d

• 12 56 34 78 20 60 40 80

• a b a c a b a d

• 1 5 3 7 2 6 4 8

(37)

Suffix Array Suffix Array

• a b a c a b a d

• 1 5 3 7 2 6 4 8

• 時間複雜度 O(NlogN)

• abacabad

• abad

• acabad

• ad

• bacabad

• bad

• cabad

• d

(38)
(39)

Suffix Array Suffix Array

• Longest Common Pre xfi

• 在 SA 中常被稱為 H 陣列

• Height 陣列

• 0 abacabad

• 3 abad

• 1 acabad

• 1 ad

• 0 bacabad

• 2 bad

• 0 cabad

• 0 d

(40)
(41)

Suffix Array Suffix Array

• Longest Common Pre xfi

• 你發現一個性質

• AAB 和他前一個位置的 BAAB 之間的 H 有什麼關係

• H(AAB~)>=H(BAAB~)-1

• 因此你可以照著字串原本的順序直接做,每個 H 都從前個順序的 H-1 開始算

• 仔細算一下,會發現這樣的時間複雜度是 O(N)

(42)

跟字串匹配沒關係啊 跟字串匹配沒關係啊

• ?

• 直接捏

• 試著在 Suffix Array 上做二分搜,然後用 H 陣列 O(1) 比對

(43)

字串技能樹 字串技能樹

KMP Z

Algorithm

Suffix

Array Hash

AC 自動機 後綴

回文 自動機 自動機 Trie

Manacher

回文算法

(44)

例題 例題

• 給你字串 A 和字串 B ,現在有 Q 筆詢問

• 每個詢問會從 A 和 B 中各切一段下來,分別為 C 和 D

• 問 : D 在 C 中出現幾次。

(45)

例題 例題

• 給一個字串 S ,求最長的 XX  子字串的長度。

• 弱化 by codeforces 319D

• 例子:

• 123abcabc456 -> abcabc

• aabbcc -> aa || bb || cc

• aaaaaa -> aaaaaa

• Len(s) <= 10^5

參考文獻

相關文件

貪心 Greedy. Lecture

• 當我們在歸類一個問題為 問題時,等於不在乎他的複雜度是 還是 之類的,只要是多項式時間就好。.

• 數學上有一個很類似的定義叫做凸函數 (convex function). • 上下顛倒後就叫凹函數

•  三分搜在有水平線的情況下,如果可以確定水平線的地方一定是 答案的話,才可以用三分搜找極值。..

錯排數

課堂補充 by

課堂補充 by qazwsxedcrfvtg14...

課堂補充 by TreapKing modified