80 lines
2.0 KiB
JavaScript
80 lines
2.0 KiB
JavaScript
|
(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;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Knuth–Morris–Pratt 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);
|