|
1 | 1 | class KMPMatcher: |
2 | 2 | def __init__(self, pattern): |
3 | | - self.pattern = pattern |
4 | | - self.lps = self.compute_lps(pattern) |
| 3 | + pass |
5 | 4 |
|
6 | 5 | # Buat longest prefix Suffix (LPS) array |
7 | 6 | def compute_lps(self, pattern): |
| 7 | + |
8 | 8 | lps = [0] * len(pattern) |
9 | 9 | length = 0 |
10 | 10 |
|
11 | 11 | i = 1 |
12 | 12 | while i < len(pattern): |
| 13 | + |
| 14 | + # prefix suffix cocok |
13 | 15 | if pattern[i] == pattern[length]: |
14 | 16 | length += 1 |
15 | 17 | lps[i] = length |
16 | 18 | i += 1 |
17 | 19 | else: |
18 | 20 | if length != 0: |
| 21 | + # panjang prefix balik ke lps[length - 1] |
19 | 22 | length = lps[length - 1] |
20 | 23 | else: |
21 | 24 | lps[i] = 0 |
22 | 25 | i += 1 |
23 | 26 | return lps |
24 | 27 |
|
25 | 28 | # cari semua posisi yang cocok, kalau tidak ada return array kosong |
26 | | - def search(self, text): |
| 29 | + def search_pattern(self, text, pattern, case_sensitive=False): |
27 | 30 | matches = [] |
28 | | - patternLen = len(self.pattern) |
| 31 | + patternLen = len(pattern) |
29 | 32 | textLen = len(text) |
30 | 33 |
|
| 34 | + if not case_sensitive: |
| 35 | + text = text.lower() |
| 36 | + pattern = pattern.lower() |
| 37 | + |
| 38 | + lps = self.compute_lps(pattern) |
| 39 | + |
31 | 40 | i = 0 |
32 | 41 | j = 0 |
33 | 42 |
|
34 | 43 | while i < textLen: |
35 | | - if self.pattern[j] == text[i]: |
| 44 | + if pattern[j] == text[i]: |
36 | 45 | i += 1 |
37 | 46 | j += 1 |
38 | 47 |
|
| 48 | + # pattern cocok ditemukan |
39 | 49 | if j == patternLen: |
40 | 50 | matches.append(i-j) |
41 | | - j = self.lps[j-1] |
42 | | - elif i < textLen and self.pattern[j] != text[i]: |
| 51 | + # posisi pattern dimulai dari index lps[j-1] |
| 52 | + j = lps[j-1] |
| 53 | + elif i < textLen and pattern[j] != text[i]: |
43 | 54 | if j != 0: |
44 | | - j = self.lps[j-1] |
| 55 | + j = lps[j-1] |
45 | 56 | else: |
46 | 57 | i += 1 |
47 | 58 | return matches |
| 59 | + |
| 60 | + def search_multiple_pattern(self, text, patterns, case_sensitive=False): |
| 61 | + results = {} |
| 62 | + |
| 63 | + if not text: |
| 64 | + return results |
| 65 | + |
| 66 | + |
| 67 | + if isinstance(patterns, str): |
| 68 | + patterns = [patterns] |
| 69 | + elif not isinstance(patterns, list): |
| 70 | + raise ValueError("Patterns must be a string or a list of strings.") |
| 71 | + |
| 72 | + for pattern in patterns: |
| 73 | + if not isinstance(pattern, str): |
| 74 | + continue |
| 75 | + |
| 76 | + pattern = pattern.strip() |
| 77 | + if pattern: |
| 78 | + matches = self.search_pattern(text, pattern, case_sensitive) |
| 79 | + results[pattern] = matches |
| 80 | + |
| 81 | + return results |
0 commit comments