1+ def rabin_karp (text , pattern , base = 256 , prime = 101 ):
2+ """
3+ Rabin-Karp Algorithm for substring search.
4+
5+ Parameters:
6+ text (str): The main text where the pattern is to be searched.
7+ pattern (str): The pattern to search for.
8+ base (int): The base used for hashing (default: 256).
9+ prime (int): A prime number used to reduce hash values (default: 101).
10+
11+ Returns:
12+ list: Starting indices of all occurrences of the pattern in the text.
13+ """
14+ n , m = len (text ), len (pattern )
15+ if m > n :
16+ return []
17+
18+ pattern_hash = 0 # Hash value for pattern
19+ text_hash = 0 # Hash value for current window in text
20+ h = 1 # The value of base^(m-1)
21+
22+ # Compute h = (base^(m-1)) % prime
23+ for _ in range (m - 1 ):
24+ h = (h * base ) % prime
25+
26+ # Compute initial hash values for pattern and first window of text
27+ for i in range (m ):
28+ pattern_hash = (base * pattern_hash + ord (pattern [i ])) % prime
29+ text_hash = (base * text_hash + ord (text [i ])) % prime
30+
31+ # List to store starting indices of pattern matches
32+ result = []
33+
34+ # Slide the pattern over text one character at a time
35+ for i in range (n - m + 1 ):
36+ # Check if the hash values match
37+ if pattern_hash == text_hash :
38+ # If hash matches, check characters one by one for a real match
39+ if text [i :i + m ] == pattern :
40+ result .append (i )
41+
42+ # Compute hash for next window of text
43+ if i < n - m :
44+ text_hash = (base * (text_hash - ord (text [i ]) * h ) + ord (text [i + m ])) % prime
45+
46+ # Make sure text_hash is positive
47+ if text_hash < 0 :
48+ text_hash += prime
49+
50+ return result
51+
52+
53+ # Example Usage
54+ if __name__ == "__main__" :
55+ text = "abracadabra"
56+ pattern = "abra"
57+ matches = rabin_karp (text , pattern )
58+ print (f"Pattern '{ pattern } ' found at indices: { matches } " )
0 commit comments