function naiveSearch(text, pattern) {
const result = [];
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) {
result.push(i);
}
}
return result;
}
console.log(naiveSearch('abracadabra', 'abra'));The pattern 'abra' appears at index 0 and again at index 7 in the text 'abracadabra'. The naive search finds both occurrences and returns their starting indices.
function computeLPS(pattern) {
const lps = 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;
}
console.log(computeLPS('ababc'));The lps array for 'ababc' is [0, 0, 1, 2, 0]. This means at index 2, the longest prefix-suffix length is 1 ('a'), at index 3 it is 2 ('ab'), and at index 4 it resets to 0.
function rabinKarp(text, pattern) {
const result = [];
const prime = 101;
const m = pattern.length;
const n = text.length;
let patternHash = 0;
let textHash = 0;
let h = 1;
for (let i = 0; i < m - 1; i++) {
h = (h * 256) % prime;
}
for (let i = 0; i < m; i++) {
patternHash = (256 * patternHash + pattern.charCodeAt(i)) % prime;
textHash = (256 * textHash + text.charCodeAt(i)) % prime;
}
for (let i = 0; i <= n - m; i++) {
if (patternHash === textHash) {
let match = true;
for (let j = 0; j < m; j++) {
if (text[i + j] !== pattern[j]) {
match = false;
break;
}
}
if (match) result.push(i);
}
if (i < n - m) {
textHash = (256 * (textHash - text.charCodeAt(i) * h) + text.charCodeAt(i + m)) % prime;
if (textHash < 0) textHash += prime;
}
}
return result;
}
console.log(rabinKarp('this is a test text for test', 'test'));The substring 'test' appears at index 10 and index 24 in the given text. The Rabin-Karp algorithm finds both positions and returns them.
function badCharTable(pattern) {
const table = {};
for (let i = 0; i < pattern.length - 1; i++) {
table[pattern[i]] = pattern.length - 1 - i;
}
return table;
}
console.log(badCharTable('example'));The bad character table for 'example' assigns shifts based on the last occurrence of each character except the last one. For example, 'e' at index 0 gets shift 6 (7 - 1 - 0).
The naive algorithm can take O(n*m) time in both worst and average cases. KMP runs in O(n) time always due to its prefix table. Rabin-Karp has average O(n+m) due to hashing but worst O(n*m) if many hash collisions occur.
