123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- 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;
|