You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.0 KiB
JavaScript

5 years ago
(function (exports) {
'use strict';
var kmp = (function () {
function builtKMPTable(str) {
var res = [];
var len;
var front;
var end;
var found;
for (var i = 1; i <= str.length; i += 1) {
front = Math.max(1, i - ((res[i - 2] || 0) + 1));
end = Math.min(i - 1, (res[i - 2] || 0) + 1);
found = false;
len = 0;
while (end >= 1 && front <= i && !found) {
if (str.substring(0, end) === str.substring(front, i)) {
found = true;
len = end;
} else {
end -= 1;
front += 1;
}
}
res[i - 1] = len;
}
return res;
}
/**
* KnuthMorrisPratt algorithm. Searches for the position of
* the first occurrence of a specified value in a string.
*
* @example
*
* var indexOf = require('path-to-algorithm/src/searching/'+
* 'knuth-morris-pratt').kmp;
* console.log(indexOf('hello', 'll')); // 2
*
* @public
* @module searching/knuth-morris-pratt
* @param {String} str String.
* @param {String} substr Substring.
* @return {Number} A Number, representing the position
* where the specified substring occurs for the first
* time, or -1 if it never occurs.
*/
function indexOf(str, substr) {
if (str === substr) {
return 0;
}
var table = builtKMPTable(substr);
var i = 0;
var j = 0;
while (i < str.length) {
if (str[i] === substr[j]) {
i += 1;
j += 1;
}
if (j === substr.length) {
return i - j;
}
if (i < str.length && str[i] !== substr[j]) {
if (j > 0 && table[j - 1] !== 0) {
j = table[j - 1];
} else {
i += 1;
j = 0;
}
}
}
return -1;
}
return indexOf;
}());
exports.kmp = kmp;
})(typeof window === 'undefined' ? module.exports : window);