mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2025-12-08 19:06:00 +00:00
60 lines
1.3 KiB
JavaScript
60 lines
1.3 KiB
JavaScript
/**
|
|
* @see https://www.youtube.com/watch?v=GTJr8OvyEVQ
|
|
* @param {string} word
|
|
* @return {number[]}
|
|
*/
|
|
function buildPatternTable(word) {
|
|
const patternTable = [0];
|
|
let prefixIndex = 0;
|
|
let suffixIndex = 1;
|
|
|
|
while (suffixIndex < word.length) {
|
|
if (word[prefixIndex] === word[suffixIndex]) {
|
|
patternTable[suffixIndex] = prefixIndex + 1;
|
|
suffixIndex += 1;
|
|
prefixIndex += 1;
|
|
} else if (prefixIndex === 0) {
|
|
patternTable[suffixIndex] = 0;
|
|
suffixIndex += 1;
|
|
} else {
|
|
prefixIndex = patternTable[prefixIndex - 1];
|
|
}
|
|
}
|
|
|
|
return patternTable;
|
|
}
|
|
|
|
/**
|
|
* @param {string} text
|
|
* @param {string} word
|
|
* @return {number}
|
|
*/
|
|
export default function knuthMorrisPratt(text, word) {
|
|
if (word.length === 0) {
|
|
return 0;
|
|
}
|
|
|
|
let textIndex = 0;
|
|
let wordIndex = 0;
|
|
|
|
const patternTable = buildPatternTable(word);
|
|
|
|
while (textIndex < text.length) {
|
|
if (text[textIndex] === word[wordIndex]) {
|
|
// We've found a match.
|
|
if (wordIndex === word.length - 1) {
|
|
return (textIndex - word.length) + 1;
|
|
}
|
|
wordIndex += 1;
|
|
textIndex += 1;
|
|
} else if (wordIndex > 0) {
|
|
wordIndex = patternTable[wordIndex - 1];
|
|
} else {
|
|
// wordIndex = 0;
|
|
textIndex += 1;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|