Skip to content

Commit a440024

Browse files
committed
feat: suffix-array-construction challenge
1 parent f052de5 commit a440024

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Challenge: Construct a suffix array (and optionally an LCP array) for a given string,
2+
# enabling very efficient pattern searches. This is an advanced challenge in string processing.
3+
# Use object-oriented programming and follow the DRY principle.
4+
5+
from suffix_array import SuffixArray
6+
7+
def main():
8+
text = "banana"
9+
sa = SuffixArray(text)
10+
suffix_arr = sa.build_suffix_array()
11+
lcp_arr = sa.build_lcp_array()
12+
print(f"Suffix Array: {suffix_arr}")
13+
print(f"LCP Array: {lcp_arr}")
14+
15+
if __name__ == "__main__":
16+
main()
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from typing import List
2+
3+
class SuffixArray:
4+
def __init__(self, text: str):
5+
self.text = text
6+
self.n = len(text)
7+
self.suffix_array = []
8+
self.lcp_array = []
9+
10+
def build_suffix_array(self) -> List[int]:
11+
self.suffix_array = sorted(range(self.n), key=lambda i: self.text[i:])
12+
return self.suffix_array
13+
14+
def build_lcp_array(self) -> List[int]:
15+
if not self.suffix_array:
16+
self.build_suffix_array()
17+
18+
self.lcp_array = [0] * self.n
19+
inv_suffix = [0] * self.n
20+
21+
for i, suffix in enumerate(self.suffix_array):
22+
inv_suffix[suffix] = i
23+
24+
k = 0
25+
for i in range(self.n):
26+
if inv_suffix[i] == self.n - 1:
27+
k = 0
28+
continue
29+
j = self.suffix_array[inv_suffix[i] + 1]
30+
while i + k < self.n and j + k < self.n and self.text[i + k] == self.text[j + k]:
31+
k += 1
32+
self.lcp_array[inv_suffix[i]] = k
33+
if k:
34+
k -= 1
35+
36+
return self.lcp_array

0 commit comments

Comments
 (0)