trie-typed 2.4.4 → 2.5.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/README.md +0 -49
- package/dist/cjs/index.cjs +302 -79
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +301 -78
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +302 -80
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +301 -79
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/common/error.d.ts +23 -0
- package/dist/types/common/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
- package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
- package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
- package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
- package/dist/types/data-structures/heap/heap.d.ts +287 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +313 -66
- package/dist/types/data-structures/queue/queue.d.ts +211 -42
- package/dist/types/data-structures/stack/stack.d.ts +174 -32
- package/dist/types/data-structures/trie/trie.d.ts +213 -43
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
- package/dist/umd/trie-typed.js +299 -76
- package/dist/umd/trie-typed.js.map +1 -1
- package/dist/umd/trie-typed.min.js +1 -1
- package/dist/umd/trie-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/common/error.ts +60 -0
- package/src/common/index.ts +2 -0
- package/src/data-structures/base/iterable-element-base.ts +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +134 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +303 -247
- package/src/data-structures/binary-tree/binary-tree.ts +542 -121
- package/src/data-structures/binary-tree/bst.ts +346 -37
- package/src/data-structures/binary-tree/red-black-tree.ts +309 -96
- package/src/data-structures/binary-tree/segment-tree.ts +372 -248
- package/src/data-structures/binary-tree/tree-map.ts +1292 -13
- package/src/data-structures/binary-tree/tree-multi-map.ts +1098 -215
- package/src/data-structures/binary-tree/tree-multi-set.ts +863 -69
- package/src/data-structures/binary-tree/tree-set.ts +1143 -15
- package/src/data-structures/graph/abstract-graph.ts +106 -1
- package/src/data-structures/graph/directed-graph.ts +223 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +299 -59
- package/src/data-structures/hash/hash-map.ts +243 -79
- package/src/data-structures/heap/heap.ts +291 -102
- package/src/data-structures/heap/max-heap.ts +48 -3
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
- package/src/data-structures/matrix/matrix.ts +425 -22
- package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
- package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
- package/src/data-structures/priority-queue/priority-queue.ts +60 -0
- package/src/data-structures/queue/deque.ts +343 -68
- package/src/data-structures/queue/queue.ts +211 -42
- package/src/data-structures/stack/stack.ts +174 -32
- package/src/data-structures/trie/trie.ts +215 -44
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
- package/src/types/data-structures/queue/deque.ts +7 -0
- package/src/utils/utils.ts +4 -2
package/README.md
CHANGED
|
@@ -35,36 +35,6 @@ yarn add trie-typed
|
|
|
35
35
|
|
|
36
36
|
[//]: # (No deletion!!! Start of Example Replace Section)
|
|
37
37
|
|
|
38
|
-
### basic Trie creation and add words
|
|
39
|
-
```typescript
|
|
40
|
-
// Create a simple Trie with initial words
|
|
41
|
-
const trie = new Trie(['apple', 'app', 'apply']);
|
|
42
|
-
|
|
43
|
-
// Verify size
|
|
44
|
-
console.log(trie.size); // 3;
|
|
45
|
-
|
|
46
|
-
// Check if words exist
|
|
47
|
-
console.log(trie.has('apple')); // true;
|
|
48
|
-
console.log(trie.has('app')); // true;
|
|
49
|
-
|
|
50
|
-
// Add a new word
|
|
51
|
-
trie.add('application');
|
|
52
|
-
console.log(trie.size); // 4;
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Trie getWords and prefix search
|
|
56
|
-
```typescript
|
|
57
|
-
const trie = new Trie(['apple', 'app', 'apply', 'application', 'apricot']);
|
|
58
|
-
|
|
59
|
-
// Get all words with prefix 'app'
|
|
60
|
-
const appWords = trie.getWords('app');
|
|
61
|
-
console.log(appWords); // contains 'app';
|
|
62
|
-
console.log(appWords); // contains 'apple';
|
|
63
|
-
console.log(appWords); // contains 'apply';
|
|
64
|
-
console.log(appWords); // contains 'application';
|
|
65
|
-
expect(appWords).not.toContain('apricot');
|
|
66
|
-
```
|
|
67
|
-
|
|
68
38
|
### Trie isPrefix and isAbsolutePrefix checks
|
|
69
39
|
```typescript
|
|
70
40
|
const trie = new Trie(['tree', 'trial', 'trick', 'trip', 'trie']);
|
|
@@ -82,25 +52,6 @@ yarn add trie-typed
|
|
|
82
52
|
console.log(trie.size); // 5;
|
|
83
53
|
```
|
|
84
54
|
|
|
85
|
-
### Trie delete and iteration
|
|
86
|
-
```typescript
|
|
87
|
-
const trie = new Trie(['car', 'card', 'care', 'careful', 'can', 'cat']);
|
|
88
|
-
|
|
89
|
-
// Delete a word
|
|
90
|
-
trie.delete('card');
|
|
91
|
-
console.log(trie.has('card')); // false;
|
|
92
|
-
|
|
93
|
-
// Word with same prefix still exists
|
|
94
|
-
console.log(trie.has('care')); // true;
|
|
95
|
-
|
|
96
|
-
// Size decreased
|
|
97
|
-
console.log(trie.size); // 5;
|
|
98
|
-
|
|
99
|
-
// Iterate through all words
|
|
100
|
-
const allWords = [...trie];
|
|
101
|
-
console.log(allWords.length); // 5;
|
|
102
|
-
```
|
|
103
|
-
|
|
104
55
|
### Trie for autocomplete search index
|
|
105
56
|
```typescript
|
|
106
57
|
// Trie is perfect for autocomplete: O(m + k) where m is prefix length, k is results
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -226,6 +226,55 @@ var IterableElementBase = class {
|
|
|
226
226
|
}
|
|
227
227
|
};
|
|
228
228
|
|
|
229
|
+
// src/common/error.ts
|
|
230
|
+
var ERR = {
|
|
231
|
+
// Range / index
|
|
232
|
+
indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
|
|
233
|
+
invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
|
|
234
|
+
// Type / argument
|
|
235
|
+
invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
|
|
236
|
+
comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
|
|
237
|
+
invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
|
|
238
|
+
notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
|
|
239
|
+
invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
|
|
240
|
+
invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
|
|
241
|
+
invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
|
|
242
|
+
reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
|
|
243
|
+
callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
|
|
244
|
+
// State / operation
|
|
245
|
+
invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
|
|
246
|
+
// Matrix
|
|
247
|
+
matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
|
|
248
|
+
matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
|
|
249
|
+
matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
|
|
250
|
+
matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
|
|
251
|
+
matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// src/common/index.ts
|
|
255
|
+
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
256
|
+
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
257
|
+
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
258
|
+
return DFSOperation2;
|
|
259
|
+
})(DFSOperation || {});
|
|
260
|
+
var Range = class {
|
|
261
|
+
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
262
|
+
this.low = low;
|
|
263
|
+
this.high = high;
|
|
264
|
+
this.includeLow = includeLow;
|
|
265
|
+
this.includeHigh = includeHigh;
|
|
266
|
+
}
|
|
267
|
+
static {
|
|
268
|
+
__name(this, "Range");
|
|
269
|
+
}
|
|
270
|
+
// Determine whether a key is within the range
|
|
271
|
+
isInRange(key, comparator) {
|
|
272
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
273
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
274
|
+
return lowCheck && highCheck;
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
229
278
|
// src/data-structures/trie/trie.ts
|
|
230
279
|
var TrieNode = class {
|
|
231
280
|
static {
|
|
@@ -353,11 +402,37 @@ var Trie = class extends IterableElementBase {
|
|
|
353
402
|
return this._size;
|
|
354
403
|
}
|
|
355
404
|
/**
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
405
|
+
* Insert one word into the trie.
|
|
406
|
+
* @remarks Time O(L), Space O(L)
|
|
407
|
+
* @param word - Word to insert.
|
|
408
|
+
* @returns True if the word was newly added.
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
* @example
|
|
421
|
+
* // basic Trie creation and add words
|
|
422
|
+
* // Create a simple Trie with initial words
|
|
423
|
+
* const trie = new Trie(['apple', 'app', 'apply']);
|
|
424
|
+
*
|
|
425
|
+
* // Verify size
|
|
426
|
+
* console.log(trie.size); // 3;
|
|
427
|
+
*
|
|
428
|
+
* // Check if words exist
|
|
429
|
+
* console.log(trie.has('apple')); // true;
|
|
430
|
+
* console.log(trie.has('app')); // true;
|
|
431
|
+
*
|
|
432
|
+
* // Add a new word
|
|
433
|
+
* trie.add('application');
|
|
434
|
+
* console.log(trie.size); // 4;
|
|
435
|
+
*/
|
|
361
436
|
add(word) {
|
|
362
437
|
word = this._caseProcess(word);
|
|
363
438
|
let cur = this.root;
|
|
@@ -378,11 +453,26 @@ var Trie = class extends IterableElementBase {
|
|
|
378
453
|
return isNewWord;
|
|
379
454
|
}
|
|
380
455
|
/**
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
456
|
+
* Insert many words from an iterable.
|
|
457
|
+
* @remarks Time O(ΣL), Space O(ΣL)
|
|
458
|
+
* @param words - Iterable of strings (or raw records if toElementFn is provided).
|
|
459
|
+
* @returns Array of per-word 'added' flags.
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
* @example
|
|
469
|
+
* // Add multiple words
|
|
470
|
+
* const trie = new Trie();
|
|
471
|
+
* trie.addMany(['cat', 'car', 'card']);
|
|
472
|
+
* console.log(trie.has('cat')); // true;
|
|
473
|
+
* console.log(trie.has('car')); // true;
|
|
474
|
+
* console.log(trie.size); // 3;
|
|
475
|
+
*/
|
|
386
476
|
addMany(words) {
|
|
387
477
|
const ans = [];
|
|
388
478
|
for (const word of words) {
|
|
@@ -395,11 +485,29 @@ var Trie = class extends IterableElementBase {
|
|
|
395
485
|
return ans;
|
|
396
486
|
}
|
|
397
487
|
/**
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
488
|
+
* Check whether a word exists.
|
|
489
|
+
* @remarks Time O(L), Space O(1)
|
|
490
|
+
* @param word - Word to search for.
|
|
491
|
+
* @returns True if present.
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
* @example
|
|
504
|
+
* // Check if a word exists
|
|
505
|
+
* const dict = new Trie(['apple', 'app', 'application']);
|
|
506
|
+
*
|
|
507
|
+
* console.log(dict.has('app')); // true;
|
|
508
|
+
* console.log(dict.has('apple')); // true;
|
|
509
|
+
* console.log(dict.has('ap')); // false;
|
|
510
|
+
*/
|
|
403
511
|
has(word) {
|
|
404
512
|
word = this._caseProcess(word);
|
|
405
513
|
let cur = this.root;
|
|
@@ -411,28 +519,83 @@ var Trie = class extends IterableElementBase {
|
|
|
411
519
|
return cur.isEnd;
|
|
412
520
|
}
|
|
413
521
|
/**
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
522
|
+
* Check whether the trie is empty.
|
|
523
|
+
* @remarks Time O(1), Space O(1)
|
|
524
|
+
* @returns True if size is 0.
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
* @example
|
|
534
|
+
* // Check if empty
|
|
535
|
+
* const trie = new Trie();
|
|
536
|
+
* console.log(trie.isEmpty()); // true;
|
|
537
|
+
* trie.add('word');
|
|
538
|
+
* console.log(trie.isEmpty()); // false;
|
|
539
|
+
*/
|
|
418
540
|
isEmpty() {
|
|
419
541
|
return this._size === 0;
|
|
420
542
|
}
|
|
421
543
|
/**
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
544
|
+
* Remove all words and reset to a fresh root.
|
|
545
|
+
* @remarks Time O(1), Space O(1)
|
|
546
|
+
* @returns void
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
* @example
|
|
556
|
+
* // Remove all words
|
|
557
|
+
* const trie = new Trie(['a', 'b', 'c']);
|
|
558
|
+
* trie.clear();
|
|
559
|
+
* console.log(trie.isEmpty()); // true;
|
|
560
|
+
*/
|
|
426
561
|
clear() {
|
|
427
562
|
this._size = 0;
|
|
428
563
|
this._root = new TrieNode("");
|
|
429
564
|
}
|
|
430
565
|
/**
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
566
|
+
* Delete one word if present.
|
|
567
|
+
* @remarks Time O(L), Space O(1)
|
|
568
|
+
* @param word - Word to delete.
|
|
569
|
+
* @returns True if a word was removed.
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
* @example
|
|
582
|
+
* // Trie delete and iteration
|
|
583
|
+
* const trie = new Trie(['car', 'card', 'care', 'careful', 'can', 'cat']);
|
|
584
|
+
*
|
|
585
|
+
* // Delete a word
|
|
586
|
+
* trie.delete('card');
|
|
587
|
+
* console.log(trie.has('card')); // false;
|
|
588
|
+
*
|
|
589
|
+
* // Word with same prefix still exists
|
|
590
|
+
* console.log(trie.has('care')); // true;
|
|
591
|
+
*
|
|
592
|
+
* // Size decreased
|
|
593
|
+
* console.log(trie.size); // 5;
|
|
594
|
+
*
|
|
595
|
+
* // Iterate through all words
|
|
596
|
+
* const allWords = [...trie];
|
|
597
|
+
* console.log(allWords.length); // 5;
|
|
598
|
+
*/
|
|
436
599
|
delete(word) {
|
|
437
600
|
word = this._caseProcess(word);
|
|
438
601
|
let isDeleted = false;
|
|
@@ -508,11 +671,29 @@ var Trie = class extends IterableElementBase {
|
|
|
508
671
|
return !cur.isEnd;
|
|
509
672
|
}
|
|
510
673
|
/**
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
674
|
+
* Check whether any word starts with input.
|
|
675
|
+
* @remarks Time O(L), Space O(1)
|
|
676
|
+
* @param input - String to test as prefix.
|
|
677
|
+
* @returns True if input matches a path from root.
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
* @example
|
|
690
|
+
* // Check if a prefix exists
|
|
691
|
+
* const trie = new Trie(['hello', 'help', 'world']);
|
|
692
|
+
*
|
|
693
|
+
* console.log(trie.hasPrefix('hel')); // true;
|
|
694
|
+
* console.log(trie.hasPrefix('wor')); // true;
|
|
695
|
+
* console.log(trie.hasPrefix('xyz')); // false;
|
|
696
|
+
*/
|
|
516
697
|
hasPrefix(input) {
|
|
517
698
|
input = this._caseProcess(input);
|
|
518
699
|
let cur = this.root;
|
|
@@ -543,10 +724,26 @@ var Trie = class extends IterableElementBase {
|
|
|
543
724
|
return commonPre === input;
|
|
544
725
|
}
|
|
545
726
|
/**
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
727
|
+
* Return the longest common prefix among all words.
|
|
728
|
+
* @remarks Time O(H), Space O(1)
|
|
729
|
+
* @returns The longest common prefix string.
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
* @example
|
|
742
|
+
* // Find shared prefix
|
|
743
|
+
* const trie = new Trie(['flower', 'flow', 'flight']);
|
|
744
|
+
*
|
|
745
|
+
* console.log(trie.getLongestCommonPrefix()); // 'fl';
|
|
746
|
+
*/
|
|
550
747
|
getLongestCommonPrefix() {
|
|
551
748
|
let commonPre = "";
|
|
552
749
|
const dfs = /* @__PURE__ */ __name((cur) => {
|
|
@@ -559,13 +756,35 @@ var Trie = class extends IterableElementBase {
|
|
|
559
756
|
return commonPre;
|
|
560
757
|
}
|
|
561
758
|
/**
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
759
|
+
* Collect words under a prefix up to a maximum count.
|
|
760
|
+
* @remarks Time O(K·L), Space O(K·L)
|
|
761
|
+
* @param [prefix] - Prefix to match; default empty string for root.
|
|
762
|
+
* @param [max] - Maximum number of words to return; default is Number.MAX_SAFE_INTEGER.
|
|
763
|
+
* @param [isAllWhenEmptyPrefix] - When true, collect from root even if prefix is empty.
|
|
764
|
+
* @returns Array of collected words (at most max).
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
* @example
|
|
777
|
+
* // Trie getWords and prefix search
|
|
778
|
+
* const trie = new Trie(['apple', 'app', 'apply', 'application', 'apricot']);
|
|
779
|
+
*
|
|
780
|
+
* // Get all words with prefix 'app'
|
|
781
|
+
* const appWords = trie.getWords('app');
|
|
782
|
+
* console.log(appWords); // contains 'app';
|
|
783
|
+
* console.log(appWords); // contains 'apple';
|
|
784
|
+
* console.log(appWords); // contains 'apply';
|
|
785
|
+
* console.log(appWords); // contains 'application';
|
|
786
|
+
* expect(appWords).not.toContain('apricot');
|
|
787
|
+
*/
|
|
569
788
|
getWords(prefix = "", max = Number.MAX_SAFE_INTEGER, isAllWhenEmptyPrefix = false) {
|
|
570
789
|
prefix = this._caseProcess(prefix);
|
|
571
790
|
const words = [];
|
|
@@ -596,22 +815,49 @@ var Trie = class extends IterableElementBase {
|
|
|
596
815
|
return words;
|
|
597
816
|
}
|
|
598
817
|
/**
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
818
|
+
* Deep clone this trie by iterating and inserting all words.
|
|
819
|
+
* @remarks Time O(ΣL), Space O(ΣL)
|
|
820
|
+
* @returns A new trie with the same words and options.
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
* @example
|
|
830
|
+
* // Create independent copy
|
|
831
|
+
* const trie = new Trie(['hello', 'world']);
|
|
832
|
+
* const copy = trie.clone();
|
|
833
|
+
* copy.delete('hello');
|
|
834
|
+
* console.log(trie.has('hello')); // true;
|
|
835
|
+
*/
|
|
603
836
|
clone() {
|
|
604
837
|
const next = this._createInstance();
|
|
605
838
|
for (const x of this) next.add(x);
|
|
606
839
|
return next;
|
|
607
840
|
}
|
|
608
841
|
/**
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
842
|
+
* Filter words into a new trie of the same class.
|
|
843
|
+
* @remarks Time O(ΣL), Space O(ΣL)
|
|
844
|
+
* @param predicate - Predicate (word, index, trie) → boolean to keep word.
|
|
845
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
846
|
+
* @returns A new trie containing words that satisfy the predicate.
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
* @example
|
|
856
|
+
* // Filter words
|
|
857
|
+
* const trie = new Trie(['cat', 'car', 'dog', 'card']);
|
|
858
|
+
* const result = trie.filter(w => w.startsWith('ca'));
|
|
859
|
+
* console.log(result.size); // 3;
|
|
860
|
+
*/
|
|
615
861
|
filter(predicate, thisArg) {
|
|
616
862
|
const results = this._createInstance();
|
|
617
863
|
let index = 0;
|
|
@@ -629,7 +875,7 @@ var Trie = class extends IterableElementBase {
|
|
|
629
875
|
for (const x of this) {
|
|
630
876
|
const v = thisArg === void 0 ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);
|
|
631
877
|
if (typeof v !== "string") {
|
|
632
|
-
throw new TypeError(
|
|
878
|
+
throw new TypeError(ERR.callbackReturnType("string", typeof v, "Trie.map"));
|
|
633
879
|
}
|
|
634
880
|
newTrie.add(v);
|
|
635
881
|
}
|
|
@@ -717,30 +963,6 @@ var Trie = class extends IterableElementBase {
|
|
|
717
963
|
return str;
|
|
718
964
|
}
|
|
719
965
|
};
|
|
720
|
-
|
|
721
|
-
// src/common/index.ts
|
|
722
|
-
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
723
|
-
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
724
|
-
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
725
|
-
return DFSOperation2;
|
|
726
|
-
})(DFSOperation || {});
|
|
727
|
-
var Range = class {
|
|
728
|
-
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
729
|
-
this.low = low;
|
|
730
|
-
this.high = high;
|
|
731
|
-
this.includeLow = includeLow;
|
|
732
|
-
this.includeHigh = includeHigh;
|
|
733
|
-
}
|
|
734
|
-
static {
|
|
735
|
-
__name(this, "Range");
|
|
736
|
-
}
|
|
737
|
-
// Determine whether a key is within the range
|
|
738
|
-
isInRange(key, comparator) {
|
|
739
|
-
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
740
|
-
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
741
|
-
return lowCheck && highCheck;
|
|
742
|
-
}
|
|
743
|
-
};
|
|
744
966
|
/**
|
|
745
967
|
* data-structure-typed
|
|
746
968
|
*
|
|
@@ -750,6 +972,7 @@ var Range = class {
|
|
|
750
972
|
*/
|
|
751
973
|
|
|
752
974
|
exports.DFSOperation = DFSOperation;
|
|
975
|
+
exports.ERR = ERR;
|
|
753
976
|
exports.Range = Range;
|
|
754
977
|
exports.Trie = Trie;
|
|
755
978
|
exports.TrieNode = TrieNode;
|