cspell-trie-lib 5.15.2 → 5.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/SimpleDictionaryParser.js +3 -3
- package/dist/lib/TrieBuilder.js +6 -6
- package/dist/lib/TrieNode.d.ts +4 -3
- package/dist/lib/consolidate.js +2 -2
- package/dist/lib/distance/distance.d.ts +35 -0
- package/dist/lib/distance/distance.js +50 -0
- package/dist/lib/distance/distanceAStar.d.ts +7 -0
- package/dist/lib/distance/distanceAStar.js +59 -0
- package/dist/lib/distance/distanceAStarWeighted.d.ts +20 -0
- package/dist/lib/distance/distanceAStarWeighted.js +104 -0
- package/dist/lib/distance/index.d.ts +3 -0
- package/dist/lib/distance/index.js +8 -0
- package/dist/lib/distance/levenshtein.d.ts +9 -0
- package/dist/lib/distance/levenshtein.js +48 -0
- package/dist/lib/distance/weightedMaps.d.ts +83 -0
- package/dist/lib/distance/weightedMaps.js +264 -0
- package/dist/lib/find.d.ts +2 -1
- package/dist/lib/find.js +3 -3
- package/dist/lib/flatten.js +1 -3
- package/dist/lib/genSuggestionsOptions.d.ts +5 -0
- package/dist/lib/genSuggestionsOptions.js +2 -1
- package/dist/lib/index.d.ts +14 -8
- package/dist/lib/index.js +56 -24
- package/dist/lib/{importExport.d.ts → io/importExport.d.ts} +1 -1
- package/dist/lib/{importExport.js → io/importExport.js} +0 -0
- package/dist/lib/{importExportV1.d.ts → io/importExportV1.d.ts} +1 -1
- package/dist/lib/{importExportV1.js → io/importExportV1.js} +4 -4
- package/dist/lib/{importExportV2.d.ts → io/importExportV2.d.ts} +1 -1
- package/dist/lib/{importExportV2.js → io/importExportV2.js} +3 -3
- package/dist/lib/{importExportV3.d.ts → io/importExportV3.d.ts} +1 -1
- package/dist/lib/{importExportV3.js → io/importExportV3.js} +4 -4
- package/dist/lib/mappers/mapDictionaryInfoToWeightMap.d.ts +26 -0
- package/dist/lib/mappers/mapDictionaryInfoToWeightMap.js +175 -0
- package/dist/lib/models/DictionaryInformation.d.ts +7 -0
- package/dist/lib/models/DictionaryInformation.js +3 -0
- package/dist/lib/models/suggestionCostsDef.d.ts +2 -0
- package/dist/lib/models/suggestionCostsDef.js +3 -0
- package/dist/lib/suggest.d.ts +4 -6
- package/dist/lib/suggest.js +8 -198
- package/dist/lib/suggestCollector.d.ts +3 -88
- package/dist/lib/suggestCollector.js +7 -151
- package/dist/lib/{orthography.d.ts → suggestions/orthography.d.ts} +0 -0
- package/dist/lib/{orthography.js → suggestions/orthography.js} +0 -0
- package/dist/lib/suggestions/suggest.d.ts +7 -0
- package/dist/lib/suggestions/suggest.js +201 -0
- package/dist/lib/{suggestAStar.d.ts → suggestions/suggestAStar.d.ts} +2 -2
- package/dist/lib/{suggestAStar.js → suggestions/suggestAStar.js} +3 -3
- package/dist/lib/suggestions/suggestCollector.d.ts +96 -0
- package/dist/lib/suggestions/suggestCollector.js +161 -0
- package/dist/lib/{util.d.ts → trie-util.d.ts} +5 -3
- package/dist/lib/{util.js → trie-util.js} +13 -3
- package/dist/lib/trie.js +12 -15
- package/dist/lib/trieRef.d.ts +2 -2
- package/dist/lib/types.d.ts +10 -0
- package/dist/lib/types.js +3 -0
- package/dist/lib/{PairingHeap.d.ts → utils/PairingHeap.d.ts} +10 -0
- package/dist/lib/{PairingHeap.js → utils/PairingHeap.js} +0 -0
- package/dist/lib/{bufferLines.d.ts → utils/bufferLines.d.ts} +0 -0
- package/dist/lib/{bufferLines.js → utils/bufferLines.js} +0 -0
- package/dist/lib/{secondChanceCache.d.ts → utils/secondChanceCache.d.ts} +0 -0
- package/dist/lib/{secondChanceCache.js → utils/secondChanceCache.js} +0 -0
- package/dist/lib/{timer.d.ts → utils/timer.d.ts} +0 -0
- package/dist/lib/{timer.js → utils/timer.js} +0 -0
- package/dist/lib/utils/util.d.ts +2 -0
- package/dist/lib/utils/util.js +8 -0
- package/dist/lib/walker.js +3 -3
- package/package.json +6 -3
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseDictionary = exports.parseLinesToDictionary = exports.parseDictionaryLines = exports.defaultParseDictionaryOptions = void 0;
|
|
4
4
|
const gensequence_1 = require("gensequence");
|
|
5
|
-
const
|
|
5
|
+
const trie_util_1 = require("./trie-util");
|
|
6
6
|
const constants_1 = require("./constants");
|
|
7
7
|
const TrieBuilder_1 = require("./TrieBuilder");
|
|
8
8
|
const _defaultOptions = {
|
|
@@ -68,14 +68,14 @@ function parseDictionaryLines(lines, options) {
|
|
|
68
68
|
return word[0] === keepCase ? word.slice(1) : word;
|
|
69
69
|
}
|
|
70
70
|
function _normalize(word) {
|
|
71
|
-
return (0,
|
|
71
|
+
return (0, trie_util_1.normalizeWord)(stripKeepCasePrefixAndQuotes(word));
|
|
72
72
|
}
|
|
73
73
|
function* mapNormalize(word) {
|
|
74
74
|
const nWord = _normalize(word);
|
|
75
75
|
const forms = new Set();
|
|
76
76
|
forms.add(nWord);
|
|
77
77
|
if (stripCaseAndAccents && !doNotNormalizePrefix.has(word[0])) {
|
|
78
|
-
for (const n of (0,
|
|
78
|
+
for (const n of (0, trie_util_1.normalizeWordForCaseInsensitive)(nWord)) {
|
|
79
79
|
if (n !== nWord)
|
|
80
80
|
forms.add(ignoreCase + n);
|
|
81
81
|
}
|
package/dist/lib/TrieBuilder.js
CHANGED
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TrieBuilder = exports.buildTrieFast = exports.buildTrie = void 0;
|
|
4
4
|
const trie_1 = require("./trie");
|
|
5
5
|
const consolidate_1 = require("./consolidate");
|
|
6
|
-
const
|
|
7
|
-
const secondChanceCache_1 = require("./secondChanceCache");
|
|
6
|
+
const trie_util_1 = require("./trie-util");
|
|
7
|
+
const secondChanceCache_1 = require("./utils/secondChanceCache");
|
|
8
8
|
/**
|
|
9
9
|
* Builds an optimized Trie from a Iterable<string>. It attempts to reduce the size of the trie
|
|
10
10
|
* by finding common endings.
|
|
@@ -21,7 +21,7 @@ exports.buildTrie = buildTrie;
|
|
|
21
21
|
* @param trieOptions options for the Trie
|
|
22
22
|
*/
|
|
23
23
|
function buildTrieFast(words, trieOptions) {
|
|
24
|
-
const root = (0,
|
|
24
|
+
const root = (0, trie_util_1.createTriFromList)(words, trieOptions);
|
|
25
25
|
return new trie_1.Trie(root, undefined);
|
|
26
26
|
}
|
|
27
27
|
exports.buildTrieFast = buildTrieFast;
|
|
@@ -42,7 +42,7 @@ class TrieBuilder {
|
|
|
42
42
|
this._canBeCached(this._eow); // this line is just for coverage reasons
|
|
43
43
|
this.signatures.set(this.signature(this._eow), this._eow);
|
|
44
44
|
this.cached.set(this._eow, this.count++);
|
|
45
|
-
this.trieOptions = Object.freeze((0,
|
|
45
|
+
this.trieOptions = Object.freeze((0, trie_util_1.mergeOptionalWithDefaults)(trieOptions));
|
|
46
46
|
if (words) {
|
|
47
47
|
this.insert(words);
|
|
48
48
|
}
|
|
@@ -51,7 +51,7 @@ class TrieBuilder {
|
|
|
51
51
|
this.lastPath[0].n = n;
|
|
52
52
|
}
|
|
53
53
|
get _root() {
|
|
54
|
-
return (0,
|
|
54
|
+
return (0, trie_util_1.trieNodeToRoot)(this.lastPath[0].n, this.trieOptions);
|
|
55
55
|
}
|
|
56
56
|
signature(n) {
|
|
57
57
|
const isWord = n.f ? '*' : '';
|
|
@@ -199,7 +199,7 @@ class TrieBuilder {
|
|
|
199
199
|
* Resets the builder
|
|
200
200
|
*/
|
|
201
201
|
reset() {
|
|
202
|
-
this._root = (0,
|
|
202
|
+
this._root = (0, trie_util_1.createTrieRoot)(this.trieOptions);
|
|
203
203
|
this.cached.clear();
|
|
204
204
|
this.signatures.clear();
|
|
205
205
|
this.signatures.set(this.signature(this._eow), this._eow);
|
package/dist/lib/TrieNode.d.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
import type { PartialWithUndefined } from './types';
|
|
1
2
|
export declare const FLAG_WORD = 1;
|
|
2
3
|
export declare class ChildMap extends Map<string, TrieNode> {
|
|
3
4
|
}
|
|
4
5
|
export interface TrieNode {
|
|
5
|
-
f?: number;
|
|
6
|
-
c?: ChildMap;
|
|
6
|
+
f?: number | undefined;
|
|
7
|
+
c?: ChildMap | undefined;
|
|
7
8
|
}
|
|
8
9
|
export interface TrieOptions {
|
|
9
10
|
compoundCharacter: string;
|
|
10
11
|
stripCaseAndAccentsPrefix: string;
|
|
11
12
|
forbiddenWordPrefix: string;
|
|
12
13
|
}
|
|
13
|
-
export declare type PartialTrieOptions =
|
|
14
|
+
export declare type PartialTrieOptions = PartialWithUndefined<TrieOptions> | undefined;
|
|
14
15
|
export interface TrieRoot extends TrieOptions {
|
|
15
16
|
c: ChildMap;
|
|
16
17
|
}
|
package/dist/lib/consolidate.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.consolidate = void 0;
|
|
4
4
|
const TrieNode_1 = require("./TrieNode");
|
|
5
|
-
const
|
|
5
|
+
const trie_util_1 = require("./trie-util");
|
|
6
6
|
/**
|
|
7
7
|
* Consolidate to DAWG
|
|
8
8
|
* @param root the root of the Trie tree
|
|
@@ -89,7 +89,7 @@ function consolidate(root) {
|
|
|
89
89
|
const eow = findEow(root) || { f: TrieNode_1.FLAG_WORD, c: undefined };
|
|
90
90
|
signatures.set(signature(eow), eow);
|
|
91
91
|
cached.set(eow, count++);
|
|
92
|
-
return (0,
|
|
92
|
+
return (0, trie_util_1.trieNodeToRoot)(process(root), root);
|
|
93
93
|
}
|
|
94
94
|
exports.consolidate = consolidate;
|
|
95
95
|
//# sourceMappingURL=consolidate.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { SuggestionCostMapDef } from '../models/suggestionCostsDef';
|
|
2
|
+
import type { WeightMap } from './weightedMaps';
|
|
3
|
+
export type { SuggestionCostMapDef } from '../models/suggestionCostsDef';
|
|
4
|
+
export type { WeightMap } from './weightedMaps';
|
|
5
|
+
/**
|
|
6
|
+
* Calculate the edit distance between any two words.
|
|
7
|
+
* Use the Damerau–Levenshtein distance algorithm.
|
|
8
|
+
* @param wordA
|
|
9
|
+
* @param wordB
|
|
10
|
+
* @param editCost - the cost of each edit (defaults to 100)
|
|
11
|
+
* @returns the edit distance.
|
|
12
|
+
*/
|
|
13
|
+
export declare function editDistance(wordA: string, wordB: string, editCost?: number): number;
|
|
14
|
+
/**
|
|
15
|
+
* Calculate the weighted edit distance between any two words.
|
|
16
|
+
* @param wordA
|
|
17
|
+
* @param wordB
|
|
18
|
+
* @param weights - the weights to use
|
|
19
|
+
* @param editCost - the cost of each edit (defaults to 100)
|
|
20
|
+
* @returns the edit distance
|
|
21
|
+
*/
|
|
22
|
+
export declare function editDistanceWeighted(wordA: string, wordB: string, weights: WeightMap, editCost?: number): number;
|
|
23
|
+
/**
|
|
24
|
+
* Collect Map definitions into a single weighted map.
|
|
25
|
+
* @param defs - list of definitions
|
|
26
|
+
* @returns A Weighted Map to be used with distance calculations.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createWeightedMap(defs: SuggestionCostMapDef[]): WeightMap;
|
|
29
|
+
/**
|
|
30
|
+
* Update a WeightedMap with a WeightedMapDef
|
|
31
|
+
* @param weightedMap - map to update
|
|
32
|
+
* @param def - the definition to use
|
|
33
|
+
*/
|
|
34
|
+
export declare function updatedWeightedMap(weightedMap: WeightMap, def: SuggestionCostMapDef): void;
|
|
35
|
+
//# sourceMappingURL=distance.d.ts.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updatedWeightedMap = exports.createWeightedMap = exports.editDistanceWeighted = exports.editDistance = void 0;
|
|
4
|
+
const distanceAStarWeighted_1 = require("./distanceAStarWeighted");
|
|
5
|
+
const levenshtein_1 = require("./levenshtein");
|
|
6
|
+
const weightedMaps_1 = require("./weightedMaps");
|
|
7
|
+
const defaultCost = 100;
|
|
8
|
+
/**
|
|
9
|
+
* Calculate the edit distance between any two words.
|
|
10
|
+
* Use the Damerau–Levenshtein distance algorithm.
|
|
11
|
+
* @param wordA
|
|
12
|
+
* @param wordB
|
|
13
|
+
* @param editCost - the cost of each edit (defaults to 100)
|
|
14
|
+
* @returns the edit distance.
|
|
15
|
+
*/
|
|
16
|
+
function editDistance(wordA, wordB, editCost = defaultCost) {
|
|
17
|
+
return (0, levenshtein_1.levenshteinDistance)(wordA, wordB) * editCost;
|
|
18
|
+
}
|
|
19
|
+
exports.editDistance = editDistance;
|
|
20
|
+
/**
|
|
21
|
+
* Calculate the weighted edit distance between any two words.
|
|
22
|
+
* @param wordA
|
|
23
|
+
* @param wordB
|
|
24
|
+
* @param weights - the weights to use
|
|
25
|
+
* @param editCost - the cost of each edit (defaults to 100)
|
|
26
|
+
* @returns the edit distance
|
|
27
|
+
*/
|
|
28
|
+
function editDistanceWeighted(wordA, wordB, weights, editCost = defaultCost) {
|
|
29
|
+
return (0, distanceAStarWeighted_1.distanceAStarWeighted)(wordA, wordB, weights, editCost);
|
|
30
|
+
}
|
|
31
|
+
exports.editDistanceWeighted = editDistanceWeighted;
|
|
32
|
+
/**
|
|
33
|
+
* Collect Map definitions into a single weighted map.
|
|
34
|
+
* @param defs - list of definitions
|
|
35
|
+
* @returns A Weighted Map to be used with distance calculations.
|
|
36
|
+
*/
|
|
37
|
+
function createWeightedMap(defs) {
|
|
38
|
+
return (0, weightedMaps_1.createWeightMap)(...defs);
|
|
39
|
+
}
|
|
40
|
+
exports.createWeightedMap = createWeightedMap;
|
|
41
|
+
/**
|
|
42
|
+
* Update a WeightedMap with a WeightedMapDef
|
|
43
|
+
* @param weightedMap - map to update
|
|
44
|
+
* @param def - the definition to use
|
|
45
|
+
*/
|
|
46
|
+
function updatedWeightedMap(weightedMap, def) {
|
|
47
|
+
(0, weightedMaps_1.addDefToWeightMap)(weightedMap, def);
|
|
48
|
+
}
|
|
49
|
+
exports.updatedWeightedMap = updatedWeightedMap;
|
|
50
|
+
//# sourceMappingURL=distance.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculate the edit distance between two words using an A* algorithm.
|
|
3
|
+
*
|
|
4
|
+
* Using basic weights, this algorithm has the same results as the Damerau-Levenshtein algorithm.
|
|
5
|
+
*/
|
|
6
|
+
export declare function distanceAStar(a: string, b: string): number;
|
|
7
|
+
//# sourceMappingURL=distanceAStar.d.ts.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.distanceAStar = void 0;
|
|
4
|
+
const PairingHeap_1 = require("../utils/PairingHeap");
|
|
5
|
+
/**
|
|
6
|
+
* Calculate the edit distance between two words using an A* algorithm.
|
|
7
|
+
*
|
|
8
|
+
* Using basic weights, this algorithm has the same results as the Damerau-Levenshtein algorithm.
|
|
9
|
+
*/
|
|
10
|
+
function distanceAStar(a, b) {
|
|
11
|
+
var _a;
|
|
12
|
+
const aN = a.length;
|
|
13
|
+
const bN = b.length;
|
|
14
|
+
const cost = 100;
|
|
15
|
+
const candidates = new PairingHeap_1.PairingHeap(compare);
|
|
16
|
+
candidates.add({ ai: 0, bi: 0, c: 0 });
|
|
17
|
+
function opSub(n) {
|
|
18
|
+
const { ai, bi, c } = n;
|
|
19
|
+
if (ai < aN && bi < bN) {
|
|
20
|
+
const cc = a[ai] === b[bi] ? c : c + cost;
|
|
21
|
+
candidates.add({ ai: ai + 1, bi: bi + 1, c: cc });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function opIns(n) {
|
|
25
|
+
const { ai, bi, c } = n;
|
|
26
|
+
if (bi < bN) {
|
|
27
|
+
candidates.add({ ai: ai, bi: bi + 1, c: c + cost });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function opDel(n) {
|
|
31
|
+
const { ai, bi, c } = n;
|
|
32
|
+
if (ai < aN) {
|
|
33
|
+
candidates.add({ ai: ai + 1, bi: bi, c: c + cost });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function opSwap(n) {
|
|
37
|
+
const { ai, bi, c } = n;
|
|
38
|
+
if (a[ai] === b[bi + 1] && a[ai + 1] === b[bi]) {
|
|
39
|
+
candidates.add({ ai: ai + 2, bi: bi + 2, c: c + cost });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
let best;
|
|
43
|
+
// const bc2 = 2 * bc;
|
|
44
|
+
while ((best = candidates.dequeue())) {
|
|
45
|
+
if (best.ai === aN && best.bi === bN)
|
|
46
|
+
break;
|
|
47
|
+
opSwap(best);
|
|
48
|
+
opIns(best);
|
|
49
|
+
opDel(best);
|
|
50
|
+
opSub(best);
|
|
51
|
+
}
|
|
52
|
+
return (_a = best === null || best === void 0 ? void 0 : best.c) !== null && _a !== void 0 ? _a : -1;
|
|
53
|
+
}
|
|
54
|
+
exports.distanceAStar = distanceAStar;
|
|
55
|
+
function compare(a, b) {
|
|
56
|
+
// Choose lowest cost or farthest Manhattan distance.
|
|
57
|
+
return a.c - b.c || b.ai + b.bi - a.ai - a.bi;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=distanceAStar.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { WeightMap } from './weightedMaps';
|
|
2
|
+
/**
|
|
3
|
+
* Calculate the edit distance between two words using an A* algorithm.
|
|
4
|
+
*
|
|
5
|
+
* Using basic weights, this algorithm has the same results as the Damerau-Levenshtein algorithm.
|
|
6
|
+
*/
|
|
7
|
+
export declare function distanceAStarWeighted(wordA: string, wordB: string, map: WeightMap, cost?: number): number;
|
|
8
|
+
export interface ExResult {
|
|
9
|
+
a: string;
|
|
10
|
+
b: string;
|
|
11
|
+
cost: number;
|
|
12
|
+
segments: {
|
|
13
|
+
a: string;
|
|
14
|
+
b: string;
|
|
15
|
+
c: number;
|
|
16
|
+
p: number;
|
|
17
|
+
}[];
|
|
18
|
+
}
|
|
19
|
+
export declare function distanceAStarWeightedEx(wordA: string, wordB: string, map: WeightMap, cost?: number): ExResult | undefined;
|
|
20
|
+
//# sourceMappingURL=distanceAStarWeighted.d.ts.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.distanceAStarWeightedEx = exports.distanceAStarWeighted = void 0;
|
|
4
|
+
const PairingHeap_1 = require("../utils/PairingHeap");
|
|
5
|
+
/**
|
|
6
|
+
* Calculate the edit distance between two words using an A* algorithm.
|
|
7
|
+
*
|
|
8
|
+
* Using basic weights, this algorithm has the same results as the Damerau-Levenshtein algorithm.
|
|
9
|
+
*/
|
|
10
|
+
function distanceAStarWeighted(wordA, wordB, map, cost = 100) {
|
|
11
|
+
const best = _distanceAStarWeightedEx(wordA, wordB, map, cost);
|
|
12
|
+
return best ? best.c + best.p : -1;
|
|
13
|
+
}
|
|
14
|
+
exports.distanceAStarWeighted = distanceAStarWeighted;
|
|
15
|
+
function distanceAStarWeightedEx(wordA, wordB, map, cost = 100) {
|
|
16
|
+
const best = _distanceAStarWeightedEx(wordA, wordB, map, cost);
|
|
17
|
+
if (!best)
|
|
18
|
+
return undefined;
|
|
19
|
+
const aa = '^' + wordA + '$';
|
|
20
|
+
const bb = '^' + wordB + '$';
|
|
21
|
+
const result = {
|
|
22
|
+
a: aa,
|
|
23
|
+
b: bb,
|
|
24
|
+
cost: best.c + best.p,
|
|
25
|
+
segments: [],
|
|
26
|
+
};
|
|
27
|
+
const segments = result.segments;
|
|
28
|
+
for (let n = best; n.f; n = n.f) {
|
|
29
|
+
const f = n.f;
|
|
30
|
+
const a = aa.slice(f.ai, n.ai);
|
|
31
|
+
const b = bb.slice(f.bi, n.bi);
|
|
32
|
+
const c = n.c - f.c;
|
|
33
|
+
const p = n.p - f.p;
|
|
34
|
+
segments.push({ a, b, c, p });
|
|
35
|
+
}
|
|
36
|
+
segments.reverse();
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
exports.distanceAStarWeightedEx = distanceAStarWeightedEx;
|
|
40
|
+
function _distanceAStarWeightedEx(wordA, wordB, map, cost = 100) {
|
|
41
|
+
// Add ^ and $ for begin/end detection.
|
|
42
|
+
const a = '^' + wordA + '$';
|
|
43
|
+
const b = '^' + wordB + '$';
|
|
44
|
+
const aN = a.length;
|
|
45
|
+
const bN = b.length;
|
|
46
|
+
const candidates = new PairingHeap_1.PairingHeap(compare);
|
|
47
|
+
candidates.add({ ai: 0, bi: 0, c: 0, p: 0, f: undefined });
|
|
48
|
+
/** Substitute / Replace */
|
|
49
|
+
function opSub(n) {
|
|
50
|
+
const { ai, bi, c, p } = n;
|
|
51
|
+
if (ai < aN && bi < bN) {
|
|
52
|
+
const cc = a[ai] === b[bi] ? c : c + cost;
|
|
53
|
+
candidates.add({ ai: ai + 1, bi: bi + 1, c: cc, p, f: n });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** Insert */
|
|
57
|
+
function opIns(n) {
|
|
58
|
+
const { ai, bi, c, p } = n;
|
|
59
|
+
if (bi < bN) {
|
|
60
|
+
candidates.add({ ai: ai, bi: bi + 1, c: c + cost, p, f: n });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** Delete */
|
|
64
|
+
function opDel(n) {
|
|
65
|
+
const { ai, bi, c, p } = n;
|
|
66
|
+
if (ai < aN) {
|
|
67
|
+
candidates.add({ ai: ai + 1, bi: bi, c: c + cost, p, f: n });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Swap adjacent letters */
|
|
71
|
+
function opSwap(n) {
|
|
72
|
+
const { ai, bi, c, p } = n;
|
|
73
|
+
if (a[ai] === b[bi + 1] && a[ai + 1] === b[bi]) {
|
|
74
|
+
candidates.add({ ai: ai + 2, bi: bi + 2, c: c + cost, p, f: n });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function opMap(n) {
|
|
78
|
+
const { ai, bi, c, p } = n;
|
|
79
|
+
const pos = { a, b, ai, bi, c, p };
|
|
80
|
+
const costCalculations = [map.calcInsDelCosts(pos), map.calcSwapCosts(pos), map.calcReplaceCosts(pos)];
|
|
81
|
+
costCalculations.forEach((iter) => {
|
|
82
|
+
for (const nn of iter) {
|
|
83
|
+
candidates.add({ ...nn, f: n });
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
let best;
|
|
88
|
+
// const bc2 = 2 * bc;
|
|
89
|
+
while ((best = candidates.dequeue())) {
|
|
90
|
+
if (best.ai === aN && best.bi === bN)
|
|
91
|
+
break;
|
|
92
|
+
opSwap(best);
|
|
93
|
+
opIns(best);
|
|
94
|
+
opDel(best);
|
|
95
|
+
opMap(best);
|
|
96
|
+
opSub(best);
|
|
97
|
+
}
|
|
98
|
+
return best;
|
|
99
|
+
}
|
|
100
|
+
function compare(a, b) {
|
|
101
|
+
// Choose lowest cost or farthest Manhattan distance.
|
|
102
|
+
return a.c - b.c || b.ai + b.bi - a.ai - a.bi;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=distanceAStarWeighted.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.editDistanceWeighted = exports.editDistance = exports.createWeightedMap = void 0;
|
|
4
|
+
var distance_1 = require("./distance");
|
|
5
|
+
Object.defineProperty(exports, "createWeightedMap", { enumerable: true, get: function () { return distance_1.createWeightedMap; } });
|
|
6
|
+
Object.defineProperty(exports, "editDistance", { enumerable: true, get: function () { return distance_1.editDistance; } });
|
|
7
|
+
Object.defineProperty(exports, "editDistanceWeighted", { enumerable: true, get: function () { return distance_1.editDistanceWeighted; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Damerau–Levenshtein distance
|
|
3
|
+
* [Damerau–Levenshtein distance - Wikipedia](https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance)
|
|
4
|
+
* @param a - first word
|
|
5
|
+
* @param b - second word
|
|
6
|
+
* @returns Distance value
|
|
7
|
+
*/
|
|
8
|
+
export declare function levenshteinDistance(a: string, b: string): number;
|
|
9
|
+
//# sourceMappingURL=levenshtein.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.levenshteinDistance = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Damerau–Levenshtein distance
|
|
6
|
+
* [Damerau–Levenshtein distance - Wikipedia](https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance)
|
|
7
|
+
* @param a - first word
|
|
8
|
+
* @param b - second word
|
|
9
|
+
* @returns Distance value
|
|
10
|
+
*/
|
|
11
|
+
function levenshteinDistance(a, b) {
|
|
12
|
+
// By prefixing with spaces, no out of bounds checks are necessary.
|
|
13
|
+
const aa = ' ' + a;
|
|
14
|
+
const bb = ' ' + b;
|
|
15
|
+
const nA = a.length + 1;
|
|
16
|
+
const nB = b.length + 1;
|
|
17
|
+
const firstRow = [];
|
|
18
|
+
for (let i = 0; i <= nA; ++i) {
|
|
19
|
+
firstRow[i] = i;
|
|
20
|
+
}
|
|
21
|
+
const matrix = [firstRow, [1].concat(firstRow), [2, 1].concat(firstRow)];
|
|
22
|
+
let ppRow = matrix[0];
|
|
23
|
+
let pRow = matrix[1];
|
|
24
|
+
for (let j = 2; j <= nB; ++j) {
|
|
25
|
+
const row = matrix[j % 3];
|
|
26
|
+
row[0] = pRow[0] + 1;
|
|
27
|
+
row[1] = pRow[1] + 1;
|
|
28
|
+
const bp = bb[j - 1];
|
|
29
|
+
const bc = bb[j];
|
|
30
|
+
let ap = aa[0];
|
|
31
|
+
for (let i = 2, i1 = 1; i <= nA; i1 = i, ++i) {
|
|
32
|
+
const ac = aa[i];
|
|
33
|
+
const c = pRow[i1] + (ac == bc ? 0 : 1);
|
|
34
|
+
const ct = ac == bp && ap == bc ? ppRow[i1 - 1] + 1 : c;
|
|
35
|
+
row[i] = Math.min(c, // substitute
|
|
36
|
+
ct, // transpose
|
|
37
|
+
pRow[i] + 1, // insert
|
|
38
|
+
row[i1] + 1 // delete
|
|
39
|
+
);
|
|
40
|
+
ap = ac;
|
|
41
|
+
}
|
|
42
|
+
ppRow = pRow;
|
|
43
|
+
pRow = row;
|
|
44
|
+
}
|
|
45
|
+
return pRow[nA];
|
|
46
|
+
}
|
|
47
|
+
exports.levenshteinDistance = levenshteinDistance;
|
|
48
|
+
//# sourceMappingURL=levenshtein.js.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { SuggestionCostMapDef } from '../models/suggestionCostsDef';
|
|
2
|
+
export declare type WeightedRepMapTrie = Record<string, WeightedRepTrieNode>;
|
|
3
|
+
interface WeightedRepTrieNode {
|
|
4
|
+
/** The nested Trie nodes */
|
|
5
|
+
r?: WeightedRepMapTrie | undefined;
|
|
6
|
+
/** The cost to replace */
|
|
7
|
+
rep?: number | undefined;
|
|
8
|
+
/** The cost to swap */
|
|
9
|
+
swap?: number | undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Costs are minimized while penalties are maximized.
|
|
13
|
+
*/
|
|
14
|
+
interface Cost {
|
|
15
|
+
/**
|
|
16
|
+
* The cost of an operation
|
|
17
|
+
* `c'' = min(c, c')`
|
|
18
|
+
*/
|
|
19
|
+
c?: number | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* The penalties applied
|
|
22
|
+
* `p'' = max(p, p')`
|
|
23
|
+
*/
|
|
24
|
+
p?: number | undefined;
|
|
25
|
+
}
|
|
26
|
+
interface TrieCost extends Cost {
|
|
27
|
+
/** nested trie nodes */
|
|
28
|
+
n?: Record<string, TrieCost>;
|
|
29
|
+
}
|
|
30
|
+
interface TrieTrieCost {
|
|
31
|
+
/** nested trie nodes */
|
|
32
|
+
n?: Record<string, TrieTrieCost>;
|
|
33
|
+
/** root of cost trie */
|
|
34
|
+
t?: Record<string, TrieCost>;
|
|
35
|
+
}
|
|
36
|
+
export interface CostPosition {
|
|
37
|
+
a: string;
|
|
38
|
+
ai: number;
|
|
39
|
+
b: string;
|
|
40
|
+
bi: number;
|
|
41
|
+
c: number;
|
|
42
|
+
p: number;
|
|
43
|
+
}
|
|
44
|
+
export interface WeightMap {
|
|
45
|
+
readonly insDel: TrieCost;
|
|
46
|
+
readonly replace: TrieTrieCost;
|
|
47
|
+
readonly swap: TrieTrieCost;
|
|
48
|
+
calcInsDelCosts(pos: CostPosition): Iterable<CostPosition>;
|
|
49
|
+
calcSwapCosts(pos: CostPosition): Iterable<CostPosition>;
|
|
50
|
+
calcReplaceCosts(pos: CostPosition): Iterable<CostPosition>;
|
|
51
|
+
}
|
|
52
|
+
export declare function createWeightMap(...defs: SuggestionCostMapDef[]): WeightMap;
|
|
53
|
+
export declare function addDefToWeightMap(map: WeightMap, def: SuggestionCostMapDef, ...defs: SuggestionCostMapDef[]): WeightMap;
|
|
54
|
+
export declare function splitMapSubstringsIterable(map: string): Iterable<string>;
|
|
55
|
+
export declare function splitMapSubstrings(map: string): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Splits a WeightedMapDef.map
|
|
58
|
+
* @param map
|
|
59
|
+
*/
|
|
60
|
+
declare function splitMap(def: Pick<SuggestionCostMapDef, 'map'>): string[][];
|
|
61
|
+
interface MatchTrieCost {
|
|
62
|
+
i: number;
|
|
63
|
+
c: number;
|
|
64
|
+
p: number;
|
|
65
|
+
}
|
|
66
|
+
declare function findTrieCostPrefixes(trie: TrieCost, str: string, i: number): Iterable<MatchTrieCost>;
|
|
67
|
+
interface MatchTrieTrieCost {
|
|
68
|
+
i: number;
|
|
69
|
+
t: TrieCost;
|
|
70
|
+
}
|
|
71
|
+
declare function findTrieTrieCostPrefixes(trie: TrieTrieCost, str: string, i: number): Iterable<MatchTrieTrieCost>;
|
|
72
|
+
export declare function prettyPrintReplace(trie: TrieTrieCost, pfx?: string, indent?: string): string;
|
|
73
|
+
export declare function prettyPrintSwap(trie: TrieTrieCost, pfx?: string, indent?: string): string;
|
|
74
|
+
export declare function prettyPrintWeightMap(map: WeightMap): string;
|
|
75
|
+
export declare function lookupReplaceCost(map: WeightMap, a: string, b: string): undefined | number;
|
|
76
|
+
export declare const __testing__: {
|
|
77
|
+
splitMap: typeof splitMap;
|
|
78
|
+
splitMapSubstrings: typeof splitMapSubstrings;
|
|
79
|
+
findTrieCostPrefixes: typeof findTrieCostPrefixes;
|
|
80
|
+
findTrieTrieCostPrefixes: typeof findTrieTrieCostPrefixes;
|
|
81
|
+
};
|
|
82
|
+
export {};
|
|
83
|
+
//# sourceMappingURL=weightedMaps.d.ts.map
|