UNPKG

@a-s8h/liblevenshtein

Version:

Various utilities regarding Levenshtein transducers.

134 lines (115 loc) 3.76 kB
// Generated by CoffeeScript 1.7.1 (function() { var Dawg, DawgNode, global; DawgNode = (function() { DawgNode.next_id = 0; function DawgNode() { this.id = DawgNode.next_id; DawgNode.next_id += 1; this['is_final'] = false; this['edges'] = {}; } DawgNode.prototype.bisect_left = function(edges, edge, lower, upper) { var i; while (lower < upper) { i = (lower + upper) >> 1; if (edges[i] < edge) { lower = i + 1; } else { upper = i; } } return lower; }; DawgNode.prototype['toString'] = function() { var edge, edges, label, node, _ref; edges = []; _ref = this['edges']; for (label in _ref) { node = _ref[label]; edge = label + node.id.toString(); edges.splice(this.bisect_left(edges, edge, 0, edges.length), 0, edge); } return (+this['is_final']) + edges.join(''); }; return DawgNode; })(); Dawg = (function() { function Dawg(dictionary) { var word, _i, _len; if (!(dictionary && typeof dictionary.length === 'number')) { throw new Error("Expected dictionary to be array-like"); } this.previous_word = ''; this['root'] = new DawgNode(); this.unchecked_nodes = []; this.minimized_nodes = {}; for (_i = 0, _len = dictionary.length; _i < _len; _i++) { word = dictionary[_i]; this['insert'](word); } this.finish(); } Dawg.prototype['insert'] = function(word) { var character, i, next_node, node, previous_word, unchecked_nodes, upper_bound; i = 0; previous_word = this.previous_word; upper_bound = word.length < previous_word.length ? word.length : previous_word.length; while (i < upper_bound && word[i] === previous_word[i]) { i += 1; } this.minimize(i); unchecked_nodes = this.unchecked_nodes; if (unchecked_nodes.length === 0) { node = this['root']; } else { node = unchecked_nodes[unchecked_nodes.length - 1][2]; } while ((character = word[i]) !== undefined) { next_node = new DawgNode(); node['edges'][character] = next_node; unchecked_nodes.push([node, character, next_node]); node = next_node; i += 1; } node['is_final'] = true; this.previous_word = word; }; Dawg.prototype.finish = function() { this.minimize(0); }; Dawg.prototype.minimize = function(lower_bound) { var character, child, child_key, j, minimized_nodes, parent, unchecked_nodes, _ref; minimized_nodes = this.minimized_nodes; unchecked_nodes = this.unchecked_nodes; j = unchecked_nodes.length; while (j > lower_bound) { _ref = unchecked_nodes.pop(), parent = _ref[0], character = _ref[1], child = _ref[2]; child_key = child.toString(); if (child_key in minimized_nodes) { parent['edges'][character] = minimized_nodes[child_key]; } else { minimized_nodes[child_key] = child; } j -= 1; } }; Dawg.prototype['accepts'] = function(word) { var edge, node, _i, _len; node = this['root']; for (_i = 0, _len = word.length; _i < _len; _i++) { edge = word[_i]; node = node['edges'][edge]; if (!node) { return false; } } return node['is_final']; }; return Dawg; })(); global = typeof exports === 'object' ? exports : typeof window === 'object' ? window : this; global['levenshtein'] || (global['levenshtein'] = {}); global['levenshtein']['DawgNode'] = DawgNode; global['levenshtein']['Dawg'] = Dawg; }).call(this);