You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.6 KiB
91 lines
2.6 KiB
2 years ago
|
var Class = require('./Class');
|
||
|
var each = require('./each');
|
||
|
|
||
|
exports = Class({
|
||
|
initialize: function Trie() {
|
||
|
this.clear();
|
||
|
},
|
||
|
add: function(word) {
|
||
|
var edges = this._edges;
|
||
|
var node = this._root;
|
||
|
this._wordsInSubtree[node]++;
|
||
|
for (var i = 0, len = word.length; i < len; i++) {
|
||
|
var edge = word[i];
|
||
|
var next = edges[node][edge];
|
||
|
if (!next) {
|
||
|
if (this._freeNodes.length) {
|
||
|
next = this._freeNodes.pop();
|
||
|
} else {
|
||
|
next = this._idx++;
|
||
|
this._isWord.push(false);
|
||
|
this._wordsInSubtree.push(0);
|
||
|
edges.push({});
|
||
|
}
|
||
|
edges[node][edge] = next;
|
||
|
}
|
||
|
this._wordsInSubtree[next]++;
|
||
|
node = next;
|
||
|
}
|
||
|
this._isWord[node] = true;
|
||
|
},
|
||
|
remove: function(word) {
|
||
|
if (!this.has(word)) {
|
||
|
return;
|
||
|
}
|
||
|
var node = this._root;
|
||
|
this._wordsInSubtree[node]--;
|
||
|
for (var i = 0, len = word.length; i < len; i++) {
|
||
|
var edge = word[i];
|
||
|
var next = this._edges[node][edge];
|
||
|
if (!--this._wordsInSubtree[next]) {
|
||
|
delete this._edges[node][edge];
|
||
|
this._freeNodes.push(next);
|
||
|
}
|
||
|
node = next;
|
||
|
}
|
||
|
this._isWord[node] = false;
|
||
|
},
|
||
|
has: function(word) {
|
||
|
var node = this._root;
|
||
|
for (var i = 0, len = word.length; i < len; i++) {
|
||
|
node = this._edges[node][word[i]];
|
||
|
if (!node) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return this._isWord[node];
|
||
|
},
|
||
|
words: function(prefix) {
|
||
|
var node = this._root;
|
||
|
for (var i = 0, len = prefix.length; i < len; i++) {
|
||
|
node = this._edges[node][prefix[i]];
|
||
|
if (!node) {
|
||
|
return [];
|
||
|
}
|
||
|
}
|
||
|
var result = [];
|
||
|
this._dfs(node, prefix, result);
|
||
|
return result;
|
||
|
},
|
||
|
clear: function() {
|
||
|
this._idx = 1;
|
||
|
this._root = 0;
|
||
|
this._edges = [{}];
|
||
|
this._isWord = [false];
|
||
|
this._wordsInSubtree = [0];
|
||
|
this._freeNodes = [];
|
||
|
},
|
||
|
_dfs: function(node, prefix, result) {
|
||
|
var _this = this;
|
||
|
if (this._isWord[node]) {
|
||
|
result.push(prefix);
|
||
|
}
|
||
|
var edges = this._edges[node];
|
||
|
each(edges, function(node, edge) {
|
||
|
return _this._dfs(node, prefix + edge, result);
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
module.exports = exports;
|