Concept Flow - KMP Pattern Matching Algorithm
Build LPS array
Start matching text and pattern
Compare characters
First build the LPS array for the pattern, then use it to efficiently match the pattern in the text by skipping unnecessary comparisons.
int[] BuildLPS(string pattern) { int[] lps = new int[pattern.Length]; int len = 0, i = 1; while (i < pattern.Length) { if (pattern[i] == pattern[len]) lps[i++] = ++len; else if (len != 0) len = lps[len - 1]; else lps[i++] = 0; } return lps; }
| Step | Operation | Pattern Index (i) | Length (len) | LPS Array State | Explanation |
|---|---|---|---|---|---|
| 1 | Initialize | i=1 | len=0 | [0, 0, 0, 0, 0] | Start building LPS array with i=1, len=0 |
| 2 | Compare pattern[1] and pattern[0] | i=1 | len=0 | [0, 0, 0, 0, 0] | No match, len=0, set lps[1]=0, i++ |
| 3 | Compare pattern[2] and pattern[0] | i=2 | len=0 | [0, 0, 0, 0, 0] | No match, len=0, set lps[2]=0, i++ |
| 4 | Compare pattern[3] and pattern[0] | i=3 | len=0 | [0, 0, 0, 1, 0] | Match, len=1, set lps[3]=1, i++ |
| 5 | Compare pattern[4] and pattern[1] | i=4 | len=1 | [0, 0, 0, 1, 2] | Match, len=2, set lps[4]=2, i++ |
| 6 | LPS array complete | i=5 | len=2 | [0, 0, 0, 1, 2] | LPS array built for pattern |
| 7 | Start matching text and pattern | textIndex=0, patIndex=0 | - | - | Begin scanning text with pattern |
| 8 | Compare text[0] and pattern[0] | patIndex=0 | - | - | Match, advance both indexes |
| 9 | Compare text[1] and pattern[1] | patIndex=1 | - | - | Match, advance both indexes |
| 10 | Compare text[2] and pattern[2] | patIndex=2 | - | - | Mismatch, use lps to shift pattern |
| 11 | Shift pattern using lps[1]=0 | patIndex=0 | - | - | Reset patIndex to 0, textIndex stays |
| 12 | Compare text[2] and pattern[0] | patIndex=0 | - | - | Match, advance both indexes |
| 13 | Compare text[3] and pattern[1] | patIndex=1 | - | - | Match, advance both indexes |
| 14 | Compare text[4] and pattern[2] | patIndex=2 | - | - | Match, advance both indexes |
| 15 | Compare text[5] and pattern[3] | patIndex=3 | - | - | Match, advance both indexes |
| 16 | Compare text[6] and pattern[4] | patIndex=4 | - | - | Match, pattern found at textIndex=2 |
| 17 | Return match index | - | - | - | Pattern found, return starting index 2 |
| Variable | Start | After Step 2 | After Step 4 | After Step 6 | After Step 10 | After Step 12 | After Step 16 | Final |
|---|---|---|---|---|---|---|---|---|
| i (pattern index for LPS) | 1 | 2 | 4 | 5 | - | - | - | - |
| len (length of longest prefix suffix) | 0 | 0 | 1 | 2 | - | - | - | - |
| lps array | [0, 0, 0, 0, 0] | [0, 0, 0, 0, 0] | [0, 0, 0, 1, 0] | [0, 0, 0, 1, 2] | - | - | - | - |
| textIndex (text scanning) | - | - | - | - | 2 | 3 | 7 | 7 |
| patIndex (pattern scanning) | - | - | - | - | 2 | 0 | 5 | 5 |
KMP Pattern Matching Algorithm: - Build LPS array for pattern to store longest prefix suffix lengths - Use LPS to skip unnecessary comparisons during matching - On mismatch, shift pattern using LPS without moving text index - Achieves O(n) time matching - Efficient for large texts and repeated patterns
string text = "ABABABC";
string pattern = "ABABC";
List<int> matches = KMPSearch(pattern, text);
Console.WriteLine(string.Join(",", matches));
// Assume KMPSearch returns list of start indices where pattern matches textint[] ComputeLPS(string pattern) {
int[] lps = new int[pattern.Length];
int length = 0;
int i = 1;
while (i < pattern.Length) {
if (pattern[i] == pattern[length]) {
length++;
lps[i] = length;
i++;
} else {
if (length != 0) {
length = lps[length];
} else {
lps[i] = 0;
i++;
}
}
}
return lps;
}Pass the test and this pattern moves unknown