programming-examples/js/Algorithms/suffix-tree.js

73 lines
1.9 KiB
JavaScript
Raw Normal View History

2019-11-15 12:59:38 +01:00
(function (exports) {
'use strict';
function Node(val) {
this.value = val;
this.nodes = {};
}
function SuffixTree() {
this.root = new Node();
}
SuffixTree.prototype.addNode = (function () {
function maxPrefix(a, b) {
var res = [];
for (var i = 0; i < Math.min(a.length, b.length); i += 1) {
if (a[i] === b[i]) {
res.push(a[i]);
} else {
return '';
}
}
return res.join('');
}
function addNode(suffix, current) {
// Empty string already exists in the suffix tree
if (!suffix) {
return;
}
// The suffix is already inside the tree
if (current.value === suffix) {
return;
}
// Insert recursively
if (current.nodes[suffix[0]]) {
return addNode(suffix.substr(1, suffix.length),
current.nodes[suffix[0]]);
}
// Find the maximum prefix and split the current node if prefix exists
var prefix = maxPrefix(current.value, suffix);
if (prefix.length) {
var temp = current.value;
var suffixSuffix = suffix.substr(prefix.length, suffix.length);
var currentSuffix = temp.substr(prefix.length, temp.length);
current.value = prefix;
addNode(currentSuffix, current);
addNode(suffixSuffix, current);
// If prefix doesn't exists add new child node
} else {
current.nodes[suffix[0]] = new Node(suffix);
}
}
return function (suffix) {
addNode(suffix, this.root);
};
}());
// O(n^2) or even O(n^3) because of maxPrefix
SuffixTree.prototype.build = function (string) {
this.root.value = string;
for (var i = 1; i < string.length; i += 1) {
this.addNode(string.substr(i, string.length));
}
};
exports.Node = Node;
exports.SuffixTree = SuffixTree;
}(typeof exports === 'undefined' ? window : exports));