Discover how to find a needle in a haystack without looking at every straw twice!
Why KMP Pattern Matching Algorithm in DSA Javascript?
Imagine you are searching for a word in a huge book by flipping every page and reading each line from start to end again and again.
This is like manually checking every position in a long text to find a pattern.
This manual search is very slow because you check many characters multiple times.
It is easy to get tired and make mistakes, especially if the text is very long or the pattern appears many times.
The KMP algorithm helps by remembering what parts of the pattern matched before.
It uses this memory to skip unnecessary checks and jump ahead smartly, making the search much faster and less tiring.
function search(text, pattern) {
for (let i = 0; i <= text.length - pattern.length; i++) {
let j = 0;
while (j < pattern.length && text[i + j] === pattern[j]) {
j++;
}
if (j === pattern.length) return i;
}
return -1;
}function kmpSearch(text, pattern) {
const lps = computeLPSArray(pattern);
let i = 0, j = 0;
while (i < text.length) {
if (pattern[j] === text[i]) {
i++; j++;
if (j === pattern.length) return i - j;
} else if (j !== 0) {
j = lps[j - 1];
} else {
i++;
}
}
return -1;
}
function computeLPSArray(pattern) {
const lps = new Array(pattern.length).fill(0);
let length = 0;
let i = 1;
while (i < pattern.length) {
if (pattern[i] === pattern[length]) {
length++;
lps[i] = length;
i++;
} else {
if (length !== 0) {
length = lps[length - 1];
} else {
lps[i] = 0;
i++;
}
}
}
return lps;
}KMP enables lightning-fast pattern searches in huge texts without rechecking characters unnecessarily.
Search engines use KMP-like algorithms to quickly find your search words inside billions of web pages.
KMP avoids repeated checks by remembering previous matches.
This makes searching patterns in text much faster and efficient.
It is very useful when working with large texts or many searches.
Practice
Solution
Step 1: Understand the problem KMP solves
KMP is designed to find all occurrences of a pattern inside a text without rechecking characters unnecessarily.Step 2: Compare with other options
Sorting, reversing strings, and factorial calculation are unrelated to pattern searching.Final Answer:
To find occurrences of a pattern string within a text efficiently -> Option BQuick Check:
KMP = Pattern searching [OK]
- Confusing KMP with sorting algorithms
- Thinking KMP reverses strings
- Assuming KMP calculates factorials
Solution
Step 1: Understand prefix array initialization
The prefix array (lps) must be initialized with zeros to store lengths of longest prefix suffix.Step 2: Check each option
const lps = new Array(pattern.length).fill(0); correctly creates an array of the pattern's length filled with zeros. const lps = Array(pattern.length); creates an array but leaves elements undefined. const lps = []; lps.length = pattern.length; sets length but elements are undefined. const lps = new Array(pattern.length).fill(null); fills with null, which is incorrect.Final Answer:
const lps = new Array(pattern.length).fill(0); -> Option DQuick Check:
Prefix array = zeros [OK]
- Leaving prefix array elements undefined
- Filling prefix array with null instead of zero
- Not initializing prefix array length
function KMPSearch(pattern, text) {
const lps = computeLPSArray(pattern);
let i = 0, j = 0;
const result = [];
while (i < text.length) {
if (pattern[j] === text[i]) {
i++; j++;
if (j === pattern.length) {
result.push(i - j);
j = lps[j - 1];
}
} else if (j !== 0) {
j = lps[j - 1];
} else {
i++;
}
}
return result;
}
function computeLPSArray(pattern) {
const lps = new Array(pattern.length).fill(0);
let length = 0, i = 1;
while (i < pattern.length) {
if (pattern[i] === pattern[length]) {
length++;
lps[i] = length;
i++;
} else if (length !== 0) {
length = lps[length - 1];
} else {
lps[i] = 0;
i++;
}
}
return lps;
}
console.log(KMPSearch('ABABC', 'ABABABCABABCBC'));Solution
Step 1: Compute LPS array for pattern 'ABABC'
LPS array is [0, 0, 1, 2, 0]. This helps skip characters on mismatch.Step 2: Trace pattern matches in text 'ABABABCABABCBC'
Pattern matches start at index 2 and again at index 7 in the text.Final Answer:
[2, 7] -> Option CQuick Check:
Match indices = [2, 7] [OK]
- Incorrect LPS array calculation
- Off-by-one errors in indices
- Confusing pattern length with text length
function computeLPSArray(pattern) {
const lps = new Array(pattern.length).fill(0);
let length = 0;
let i = 0;
while (i < pattern.length) {
if (pattern[i] === pattern[length]) {
length++;
lps[i] = length;
i++;
} else if (length !== 0) {
length = lps[length - 1];
} else {
lps[i] = 0;
i++;
}
}
return lps;
}Solution
Step 1: Check loop initialization
The prefix array computation starts from index 1 because index 0 always has lps value 0.Step 2: Identify impact of starting at i=0
Starting at i=0 causes comparing pattern[0] with pattern[0] unnecessarily and overwrites lps[0], which should remain 0.Final Answer:
The loop should start with i = 1, not i = 0 -> Option AQuick Check:
Start loop at 1 for prefix array [OK]
- Starting loop at 0
- Initializing length incorrectly
- Filling lps with wrong values
Solution
Step 1: Understand overlapping matches
Overlapping matches require continuing search from the longest proper prefix which is also suffix, not restarting.Step 2: Apply correct jump after match
Setting j = lps[j - 1] after a match allows the algorithm to find overlapping occurrences without missing any.Final Answer:
After a match, set j = lps[j - 1] instead of resetting j to 0 -> Option AQuick Check:
Use lps jump to count overlaps [OK]
- Resetting j to 0 after match
- Skipping characters by incrementing i too much
- Not handling overlaps correctly
Ready to prove it?
Pass the test and this pattern moves unknown
