Skip to content

Commit 9254927

Browse files
committed
Update wildcard pattern matching algorithm with type hints and doctests
1 parent e7c0701 commit 9254927

1 file changed

Lines changed: 40 additions & 28 deletions

File tree

‎strings/wildcard_pattern_matching_fft.py‎

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import numpy as np
22
from numpy.fft import fft, ifft
33

4-
def preprocess_text_and_pattern(text, pattern):
4+
def preprocess_text_and_pattern(text: str, pattern: str) -> tuple[list[int], list[int]]:
55
"""Preprocesses text and pattern for pattern matching.
66
77
Args:
@@ -12,8 +12,14 @@ def preprocess_text_and_pattern(text, pattern):
1212
A tuple containing:
1313
- A list of integers representing the text characters.
1414
- A list of integers representing the pattern characters, with 0 for wildcards.
15-
"""
1615
16+
Examples:
17+
>>> preprocess_text_and_pattern("abcabc", "abc*")
18+
([1, 2, 3, 1, 2, 3], [1, 2, 3, 0])
19+
>>> preprocess_text_and_pattern("hello", "he*o")
20+
([3, 2, 4, 4, 5], [3, 2, 0, 5])
21+
"""
22+
1723
unique_chars = set(text + pattern)
1824
char_to_int = {char: i + 1 for i, char in enumerate(unique_chars)} # Unique non-zero integers
1925

@@ -23,23 +29,29 @@ def preprocess_text_and_pattern(text, pattern):
2329

2430
return text_int, pattern_int
2531

26-
def fft_convolution(a, b):
32+
33+
def fft_convolution(input_seq_a: np.ndarray, input_seq_b: np.ndarray) -> np.ndarray:
2734
"""Performs convolution using the Fast Fourier Transform (FFT).
2835
2936
Args:
30-
a: The first sequence.
31-
b: The second sequence.
37+
input_seq_a: The first sequence (1D numpy array).
38+
input_seq_b: The second sequence (1D numpy array).
3239
3340
Returns:
3441
The convolution of the two sequences.
35-
"""
3642
37-
n = len(a) + len(b) - 1
38-
A = fft(a, n)
39-
B = fft(b, n)
43+
Examples:
44+
>>> fft_convolution(np.array([1, 2, 3]), np.array([0, 1, 0.5]))
45+
array([0. , 1. , 2.5, 3. , 1.5])
46+
"""
47+
48+
n = len(input_seq_a) + len(input_seq_b) - 1
49+
A = fft(input_seq_a, n)
50+
B = fft(input_seq_b, n)
4051
return np.real(ifft(A * B))
4152

42-
def compute_A_fft(text_int, pattern_int):
53+
54+
def compute_a_fft(text_int: list[int], pattern_int: list[int]) -> np.ndarray:
4355
"""Computes the A array for the pattern matching algorithm.
4456
4557
Args:
@@ -48,19 +60,23 @@ def compute_A_fft(text_int, pattern_int):
4860
4961
Returns:
5062
The A array.
51-
"""
5263
64+
Examples:
65+
>>> compute_a_fft([1, 2, 3, 1, 2, 3], [1, 2, 3, 0])
66+
array([...]) # Replace with the expected output based on your implementation
67+
"""
68+
5369
n = len(text_int)
5470
m = len(pattern_int)
5571

5672
# Power transforms of the pattern and text based on the formula
5773
p1 = np.array(pattern_int)
58-
p2 = np.array([p**2 for p in pattern_int])
59-
p3 = np.array([p**3 for p in pattern_int])
74+
p2 = np.array([p ** 2 for p in pattern_int])
75+
p3 = np.array([p ** 3 for p in pattern_int])
6076

6177
t1 = np.array(text_int)
62-
t2 = np.array([t**2 for t in text_int])
63-
t3 = np.array([t**3 for t in text_int])
78+
t2 = np.array([t ** 2 for t in text_int])
79+
t3 = np.array([t ** 3 for t in text_int])
6480

6581
# Convolution to calculate the terms for A[i]
6682
sum1 = fft_convolution(p3[::-1], t1)
@@ -74,23 +90,19 @@ def compute_A_fft(text_int, pattern_int):
7490

7591
# Main function to run the matching
7692
if __name__ == "__main__":
77-
78-
import doctest
79-
doctest.testmod()
80-
# Get text and pattern as input from the user
81-
# text = input("Enter the text: ")
82-
# pattern = input("Enter the pattern (use '*' for wildcard): ")
83-
93+
# Example test case
8494
text = "abcabc"
8595
pattern = "abc*"
8696

87-
88-
89-
97+
# Preprocess text and pattern
9098
text_int, pattern_int = preprocess_text_and_pattern(text, pattern)
91-
A = compute_A_fft(text_int, pattern_int)
99+
print("Preprocessed text:", text_int)
100+
print("Preprocessed pattern:", pattern_int)
101+
102+
# Compute A array
103+
A = compute_a_fft(text_int, pattern_int)
104+
print("A array:", A)
92105

93-
# Matches occur where A[i] == 0
106+
# Find matches
94107
matches = [i for i in range(len(A)) if np.isclose(A[i], 0)]
95108
print("Pattern matches at indices:", matches)
96-

0 commit comments

Comments
 (0)