stack-typed 2.0.5 → 2.1.1
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/data-structures/base/iterable-element-base.d.ts +186 -83
- package/dist/data-structures/base/iterable-element-base.js +149 -107
- package/dist/data-structures/base/iterable-entry-base.d.ts +95 -119
- package/dist/data-structures/base/iterable-entry-base.js +59 -116
- package/dist/data-structures/base/linear-base.d.ts +250 -192
- package/dist/data-structures/base/linear-base.js +137 -274
- package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
- package/dist/data-structures/binary-tree/avl-tree-counter.js +171 -205
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +135 -87
- package/dist/data-structures/binary-tree/avl-tree.d.ts +138 -149
- package/dist/data-structures/binary-tree/avl-tree.js +208 -195
- package/dist/data-structures/binary-tree/binary-tree.d.ts +476 -632
- package/dist/data-structures/binary-tree/binary-tree.js +602 -873
- package/dist/data-structures/binary-tree/bst.d.ts +258 -306
- package/dist/data-structures/binary-tree/bst.js +505 -481
- package/dist/data-structures/binary-tree/red-black-tree.d.ts +107 -179
- package/dist/data-structures/binary-tree/red-black-tree.js +114 -209
- package/dist/data-structures/binary-tree/tree-counter.d.ts +132 -154
- package/dist/data-structures/binary-tree/tree-counter.js +172 -203
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
- package/dist/data-structures/binary-tree/tree-multi-map.js +105 -85
- package/dist/data-structures/graph/abstract-graph.d.ts +238 -233
- package/dist/data-structures/graph/abstract-graph.js +267 -237
- package/dist/data-structures/graph/directed-graph.d.ts +108 -224
- package/dist/data-structures/graph/directed-graph.js +146 -233
- package/dist/data-structures/graph/map-graph.d.ts +49 -55
- package/dist/data-structures/graph/map-graph.js +56 -59
- package/dist/data-structures/graph/undirected-graph.d.ts +103 -146
- package/dist/data-structures/graph/undirected-graph.js +129 -149
- package/dist/data-structures/hash/hash-map.d.ts +164 -338
- package/dist/data-structures/hash/hash-map.js +270 -457
- package/dist/data-structures/heap/heap.d.ts +214 -289
- package/dist/data-structures/heap/heap.js +340 -349
- package/dist/data-structures/heap/max-heap.d.ts +11 -47
- package/dist/data-structures/heap/max-heap.js +11 -66
- package/dist/data-structures/heap/min-heap.d.ts +12 -47
- package/dist/data-structures/heap/min-heap.js +11 -66
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
- package/dist/data-structures/linked-list/doubly-linked-list.js +368 -494
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +261 -310
- package/dist/data-structures/linked-list/singly-linked-list.js +447 -466
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +0 -107
- package/dist/data-structures/linked-list/skip-linked-list.js +0 -100
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
- package/dist/data-structures/priority-queue/max-priority-queue.js +11 -78
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
- package/dist/data-structures/priority-queue/min-priority-queue.js +10 -79
- package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -61
- package/dist/data-structures/priority-queue/priority-queue.js +8 -83
- package/dist/data-structures/queue/deque.d.ts +227 -254
- package/dist/data-structures/queue/deque.js +309 -348
- package/dist/data-structures/queue/queue.d.ts +180 -201
- package/dist/data-structures/queue/queue.js +265 -248
- package/dist/data-structures/stack/stack.d.ts +124 -102
- package/dist/data-structures/stack/stack.js +181 -125
- package/dist/data-structures/trie/trie.d.ts +164 -165
- package/dist/data-structures/trie/trie.js +189 -172
- package/dist/interfaces/binary-tree.d.ts +56 -6
- package/dist/interfaces/graph.d.ts +16 -0
- package/dist/types/data-structures/base/base.d.ts +1 -1
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -0
- package/dist/types/utils/utils.d.ts +1 -0
- package/dist/utils/utils.d.ts +1 -1
- package/dist/utils/utils.js +2 -1
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +238 -115
- package/src/data-structures/base/iterable-entry-base.ts +96 -120
- package/src/data-structures/base/linear-base.ts +271 -277
- package/src/data-structures/binary-tree/avl-tree-counter.ts +196 -217
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +188 -102
- package/src/data-structures/binary-tree/avl-tree.ts +237 -206
- package/src/data-structures/binary-tree/binary-tree.ts +665 -896
- package/src/data-structures/binary-tree/bst.ts +565 -572
- package/src/data-structures/binary-tree/red-black-tree.ts +157 -223
- package/src/data-structures/binary-tree/tree-counter.ts +195 -219
- package/src/data-structures/binary-tree/tree-multi-map.ts +127 -98
- package/src/data-structures/graph/abstract-graph.ts +339 -264
- package/src/data-structures/graph/directed-graph.ts +146 -236
- package/src/data-structures/graph/map-graph.ts +63 -60
- package/src/data-structures/graph/undirected-graph.ts +129 -152
- package/src/data-structures/hash/hash-map.ts +274 -496
- package/src/data-structures/heap/heap.ts +389 -402
- package/src/data-structures/heap/max-heap.ts +12 -76
- package/src/data-structures/heap/min-heap.ts +13 -76
- package/src/data-structures/linked-list/doubly-linked-list.ts +426 -530
- package/src/data-structures/linked-list/singly-linked-list.ts +495 -517
- package/src/data-structures/linked-list/skip-linked-list.ts +1 -108
- package/src/data-structures/priority-queue/max-priority-queue.ts +12 -87
- package/src/data-structures/priority-queue/min-priority-queue.ts +11 -88
- package/src/data-structures/priority-queue/priority-queue.ts +3 -92
- package/src/data-structures/queue/deque.ts +381 -357
- package/src/data-structures/queue/queue.ts +310 -264
- package/src/data-structures/stack/stack.ts +217 -131
- package/src/data-structures/trie/trie.ts +240 -175
- package/src/interfaces/binary-tree.ts +240 -6
- package/src/interfaces/graph.ts +37 -0
- package/src/types/data-structures/base/base.ts +5 -5
- package/src/types/data-structures/graph/abstract-graph.ts +5 -0
- package/src/types/utils/utils.ts +2 -0
- package/src/utils/utils.ts +9 -14
|
@@ -5,10 +5,21 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
+
|
|
8
9
|
import type { ElementCallback, TrieOptions } from '../../types';
|
|
9
10
|
import { IterableElementBase } from '../base';
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Node used by Trie to store one character and its children.
|
|
14
|
+
* @remarks Time O(1), Space O(1)
|
|
15
|
+
*/
|
|
11
16
|
export class TrieNode {
|
|
17
|
+
/**
|
|
18
|
+
* Create a Trie node with a character key.
|
|
19
|
+
* @remarks Time O(1), Space O(1)
|
|
20
|
+
* @returns New TrieNode instance.
|
|
21
|
+
*/
|
|
22
|
+
|
|
12
23
|
constructor(key: string) {
|
|
13
24
|
this._key = key;
|
|
14
25
|
this._isEnd = false;
|
|
@@ -18,18 +29,22 @@ export class TrieNode {
|
|
|
18
29
|
protected _key: string;
|
|
19
30
|
|
|
20
31
|
/**
|
|
21
|
-
*
|
|
22
|
-
* @
|
|
32
|
+
* Get the character key of this node.
|
|
33
|
+
* @remarks Time O(1), Space O(1)
|
|
34
|
+
* @returns Character key string.
|
|
23
35
|
*/
|
|
36
|
+
|
|
24
37
|
get key(): string {
|
|
25
38
|
return this._key;
|
|
26
39
|
}
|
|
27
40
|
|
|
28
41
|
/**
|
|
29
|
-
*
|
|
30
|
-
* @
|
|
31
|
-
*
|
|
42
|
+
* Set the character key of this node.
|
|
43
|
+
* @remarks Time O(1), Space O(1)
|
|
44
|
+
* @param value - New character key.
|
|
45
|
+
* @returns void
|
|
32
46
|
*/
|
|
47
|
+
|
|
33
48
|
set key(value: string) {
|
|
34
49
|
this._key = value;
|
|
35
50
|
}
|
|
@@ -37,21 +52,22 @@ export class TrieNode {
|
|
|
37
52
|
protected _children: Map<string, TrieNode>;
|
|
38
53
|
|
|
39
54
|
/**
|
|
40
|
-
*
|
|
41
|
-
* @
|
|
42
|
-
*
|
|
55
|
+
* Get the child map of this node.
|
|
56
|
+
* @remarks Time O(1), Space O(1)
|
|
57
|
+
* @returns Map from character to child node.
|
|
43
58
|
*/
|
|
59
|
+
|
|
44
60
|
get children(): Map<string, TrieNode> {
|
|
45
61
|
return this._children;
|
|
46
62
|
}
|
|
47
63
|
|
|
48
64
|
/**
|
|
49
|
-
*
|
|
50
|
-
* @
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* current TrieNode.
|
|
65
|
+
* Replace the child map of this node.
|
|
66
|
+
* @remarks Time O(1), Space O(1)
|
|
67
|
+
* @param value - New map of character → node.
|
|
68
|
+
* @returns void
|
|
54
69
|
*/
|
|
70
|
+
|
|
55
71
|
set children(value: Map<string, TrieNode>) {
|
|
56
72
|
this._children = value;
|
|
57
73
|
}
|
|
@@ -59,24 +75,31 @@ export class TrieNode {
|
|
|
59
75
|
protected _isEnd: boolean;
|
|
60
76
|
|
|
61
77
|
/**
|
|
62
|
-
*
|
|
63
|
-
* @
|
|
78
|
+
* Check whether this node marks the end of a word.
|
|
79
|
+
* @remarks Time O(1), Space O(1)
|
|
80
|
+
* @returns True if this node ends a word.
|
|
64
81
|
*/
|
|
82
|
+
|
|
65
83
|
get isEnd(): boolean {
|
|
66
84
|
return this._isEnd;
|
|
67
85
|
}
|
|
68
86
|
|
|
69
87
|
/**
|
|
70
|
-
*
|
|
71
|
-
* @
|
|
72
|
-
*
|
|
88
|
+
* Mark this node as the end of a word or not.
|
|
89
|
+
* @remarks Time O(1), Space O(1)
|
|
90
|
+
* @param value - Whether this node ends a word.
|
|
91
|
+
* @returns void
|
|
73
92
|
*/
|
|
93
|
+
|
|
74
94
|
set isEnd(value: boolean) {
|
|
75
95
|
this._isEnd = value;
|
|
76
96
|
}
|
|
77
97
|
}
|
|
78
98
|
|
|
79
99
|
/**
|
|
100
|
+
* Prefix tree (Trie) for fast prefix queries and word storage.
|
|
101
|
+
* @remarks Time O(1), Space O(1)
|
|
102
|
+
* @template R
|
|
80
103
|
* 1. Node Structure: Each node in a Trie represents a string (or a part of a string). The root node typically represents an empty string.
|
|
81
104
|
* 2. Child Node Relationship: Each node's children represent the strings that can be formed by adding one character to the string at the current node. For example, if a node represents the string 'ca', one of its children might represent 'cat'.
|
|
82
105
|
* 3. Fast Retrieval: Trie allows retrieval in O(m) time complexity, where m is the length of the string to be searched.
|
|
@@ -172,17 +195,13 @@ export class TrieNode {
|
|
|
172
195
|
*/
|
|
173
196
|
export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
174
197
|
/**
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* @param
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* value.
|
|
181
|
-
* @param [options] - The `options` parameter in the constructor is an optional object that can
|
|
182
|
-
* contain configuration options for the Trie data structure. One of the options it can have is
|
|
183
|
-
* `caseSensitive`, which is a boolean value indicating whether the Trie should be case-sensitive or
|
|
184
|
-
* not. If `caseSensitive` is set to `
|
|
198
|
+
* Create a Trie and optionally bulk-insert words.
|
|
199
|
+
* @remarks Time O(totalChars), Space O(totalChars)
|
|
200
|
+
* @param [words] - Iterable of strings (or raw records if toElementFn is provided).
|
|
201
|
+
* @param [options] - Options such as toElementFn and caseSensitive.
|
|
202
|
+
* @returns New Trie instance.
|
|
185
203
|
*/
|
|
204
|
+
|
|
186
205
|
constructor(words: Iterable<string> | Iterable<R> = [], options?: TrieOptions<R>) {
|
|
187
206
|
super(options);
|
|
188
207
|
if (options) {
|
|
@@ -197,9 +216,11 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
197
216
|
protected _size: number = 0;
|
|
198
217
|
|
|
199
218
|
/**
|
|
200
|
-
*
|
|
201
|
-
* @
|
|
219
|
+
* Get the number of stored words.
|
|
220
|
+
* @remarks Time O(1), Space O(1)
|
|
221
|
+
* @returns Word count.
|
|
202
222
|
*/
|
|
223
|
+
|
|
203
224
|
get size(): number {
|
|
204
225
|
return this._size;
|
|
205
226
|
}
|
|
@@ -207,9 +228,11 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
207
228
|
protected _caseSensitive: boolean = true;
|
|
208
229
|
|
|
209
230
|
/**
|
|
210
|
-
*
|
|
211
|
-
* @
|
|
231
|
+
* Get whether comparisons are case-sensitive.
|
|
232
|
+
* @remarks Time O(1), Space O(1)
|
|
233
|
+
* @returns True if case-sensitive.
|
|
212
234
|
*/
|
|
235
|
+
|
|
213
236
|
get caseSensitive(): boolean {
|
|
214
237
|
return this._caseSensitive;
|
|
215
238
|
}
|
|
@@ -217,21 +240,32 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
217
240
|
protected _root: TrieNode = new TrieNode('');
|
|
218
241
|
|
|
219
242
|
/**
|
|
220
|
-
*
|
|
221
|
-
* @
|
|
243
|
+
* Get the root node.
|
|
244
|
+
* @remarks Time O(1), Space O(1)
|
|
245
|
+
* @returns Root TrieNode.
|
|
222
246
|
*/
|
|
247
|
+
|
|
223
248
|
get root() {
|
|
224
249
|
return this._root;
|
|
225
250
|
}
|
|
226
251
|
|
|
227
252
|
/**
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
253
|
+
* (Protected) Get total count for base class iteration.
|
|
254
|
+
* @remarks Time O(1), Space O(1)
|
|
255
|
+
* @returns Total number of elements.
|
|
256
|
+
*/
|
|
257
|
+
|
|
258
|
+
protected get _total() {
|
|
259
|
+
return this._size;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Insert one word into the trie.
|
|
264
|
+
* @remarks Time O(L), Space O(L)
|
|
265
|
+
* @param word - Word to insert.
|
|
266
|
+
* @returns True if the word was newly added.
|
|
234
267
|
*/
|
|
268
|
+
|
|
235
269
|
add(word: string): boolean {
|
|
236
270
|
word = this._caseProcess(word);
|
|
237
271
|
let cur = this.root;
|
|
@@ -253,17 +287,12 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
253
287
|
}
|
|
254
288
|
|
|
255
289
|
/**
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
* them using a provided function if available, and adds them to a data structure while returning an
|
|
261
|
-
* array of boolean values indicating success.
|
|
262
|
-
* @param {Iterable<string> | Iterable<R>} words - The `words` parameter in the `addMany` function is
|
|
263
|
-
* an iterable that contains either strings or elements of type `R`.
|
|
264
|
-
* @returns The `addMany` method returns an array of boolean values indicating whether each word in
|
|
265
|
-
* the input iterable was successfully added to the data structure.
|
|
290
|
+
* Insert many words from an iterable.
|
|
291
|
+
* @remarks Time O(ΣL), Space O(ΣL)
|
|
292
|
+
* @param words - Iterable of strings (or raw records if toElementFn is provided).
|
|
293
|
+
* @returns Array of per-word 'added' flags.
|
|
266
294
|
*/
|
|
295
|
+
|
|
267
296
|
addMany(words: Iterable<string> | Iterable<R>): boolean[] {
|
|
268
297
|
const ans: boolean[] = [];
|
|
269
298
|
for (const word of words) {
|
|
@@ -277,13 +306,12 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
277
306
|
}
|
|
278
307
|
|
|
279
308
|
/**
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
* @param {string} word - The word to check for.
|
|
285
|
-
* @returns {boolean} True if the word is present in the Trie.
|
|
309
|
+
* Check whether a word exists.
|
|
310
|
+
* @remarks Time O(L), Space O(1)
|
|
311
|
+
* @param word - Word to search for.
|
|
312
|
+
* @returns True if present.
|
|
286
313
|
*/
|
|
314
|
+
|
|
287
315
|
override has(word: string): boolean {
|
|
288
316
|
word = this._caseProcess(word);
|
|
289
317
|
let cur = this.root;
|
|
@@ -296,35 +324,33 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
296
324
|
}
|
|
297
325
|
|
|
298
326
|
/**
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
* The isEmpty function checks if the size of the queue is 0.
|
|
303
|
-
* @return True if the size of the queue is 0
|
|
327
|
+
* Check whether the trie is empty.
|
|
328
|
+
* @remarks Time O(1), Space O(1)
|
|
329
|
+
* @returns True if size is 0.
|
|
304
330
|
*/
|
|
331
|
+
|
|
305
332
|
isEmpty(): boolean {
|
|
306
333
|
return this._size === 0;
|
|
307
334
|
}
|
|
308
335
|
|
|
309
336
|
/**
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
* The clear function resets the size of the Trie to 0 and creates a new root TrieNode.
|
|
337
|
+
* Remove all words and reset to a fresh root.
|
|
338
|
+
* @remarks Time O(1), Space O(1)
|
|
339
|
+
* @returns void
|
|
314
340
|
*/
|
|
341
|
+
|
|
315
342
|
clear(): void {
|
|
316
343
|
this._size = 0;
|
|
317
344
|
this._root = new TrieNode('');
|
|
318
345
|
}
|
|
319
346
|
|
|
320
347
|
/**
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
* @param{string} word - The word to delete.
|
|
326
|
-
* @returns {boolean} True if the word was successfully removed.
|
|
348
|
+
* Delete one word if present.
|
|
349
|
+
* @remarks Time O(L), Space O(1)
|
|
350
|
+
* @param word - Word to delete.
|
|
351
|
+
* @returns True if a word was removed.
|
|
327
352
|
*/
|
|
353
|
+
|
|
328
354
|
delete(word: string): boolean {
|
|
329
355
|
word = this._caseProcess(word);
|
|
330
356
|
let isDeleted = false;
|
|
@@ -362,15 +388,11 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
362
388
|
}
|
|
363
389
|
|
|
364
390
|
/**
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
* The function `getHeight` calculates the height of a trie data structure starting from the root
|
|
369
|
-
* node.
|
|
370
|
-
* @returns The `getHeight` method returns the maximum depth or height of the trie tree starting from
|
|
371
|
-
* the root node. It calculates the depth using a breadth-first search (BFS) traversal of the trie
|
|
372
|
-
* tree and returns the maximum depth found.
|
|
391
|
+
* Compute the height (max depth) of the trie.
|
|
392
|
+
* @remarks Time O(N), Space O(H)
|
|
393
|
+
* @returns Maximum depth from root to a leaf.
|
|
373
394
|
*/
|
|
395
|
+
|
|
374
396
|
getHeight(): number {
|
|
375
397
|
const startNode = this.root;
|
|
376
398
|
let maxDepth = 0;
|
|
@@ -392,13 +414,12 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
392
414
|
}
|
|
393
415
|
|
|
394
416
|
/**
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
* @param {string} input - The input string to check.
|
|
400
|
-
* @returns {boolean} True if it's an absolute prefix in the Trie.
|
|
417
|
+
* Check whether input is a proper prefix of at least one word.
|
|
418
|
+
* @remarks Time O(L), Space O(1)
|
|
419
|
+
* @param input - String to test as prefix.
|
|
420
|
+
* @returns True if input is a prefix but not a full word.
|
|
401
421
|
*/
|
|
422
|
+
|
|
402
423
|
hasPurePrefix(input: string): boolean {
|
|
403
424
|
input = this._caseProcess(input);
|
|
404
425
|
let cur = this.root;
|
|
@@ -411,13 +432,12 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
411
432
|
}
|
|
412
433
|
|
|
413
434
|
/**
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
* @param {string} input - The input string representing the prefix to check.
|
|
419
|
-
* @returns {boolean} True if it's a prefix in the Trie.
|
|
435
|
+
* Check whether any word starts with input.
|
|
436
|
+
* @remarks Time O(L), Space O(1)
|
|
437
|
+
* @param input - String to test as prefix.
|
|
438
|
+
* @returns True if input matches a path from root.
|
|
420
439
|
*/
|
|
440
|
+
|
|
421
441
|
hasPrefix(input: string): boolean {
|
|
422
442
|
input = this._caseProcess(input);
|
|
423
443
|
let cur = this.root;
|
|
@@ -430,13 +450,12 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
430
450
|
}
|
|
431
451
|
|
|
432
452
|
/**
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
* @param {string} input - The input string representing the common prefix to check for.
|
|
438
|
-
* @returns {boolean} True if it's a common prefix in the Trie.
|
|
453
|
+
* Check whether the trie’s longest common prefix equals input.
|
|
454
|
+
* @remarks Time O(min(H,L)), Space O(1)
|
|
455
|
+
* @param input - Candidate longest common prefix.
|
|
456
|
+
* @returns True if input equals the common prefix.
|
|
439
457
|
*/
|
|
458
|
+
|
|
440
459
|
hasCommonPrefix(input: string): boolean {
|
|
441
460
|
input = this._caseProcess(input);
|
|
442
461
|
let commonPre = '';
|
|
@@ -452,12 +471,11 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
452
471
|
}
|
|
453
472
|
|
|
454
473
|
/**
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
* Get the longest common prefix among all the words stored in the Trie.
|
|
459
|
-
* @returns {string} The longest common prefix found in the Trie.
|
|
474
|
+
* Return the longest common prefix among all words.
|
|
475
|
+
* @remarks Time O(H), Space O(1)
|
|
476
|
+
* @returns The longest common prefix string.
|
|
460
477
|
*/
|
|
478
|
+
|
|
461
479
|
getLongestCommonPrefix(): string {
|
|
462
480
|
let commonPre = '';
|
|
463
481
|
const dfs = (cur: TrieNode) => {
|
|
@@ -471,16 +489,14 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
471
489
|
}
|
|
472
490
|
|
|
473
491
|
/**
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
* @param
|
|
479
|
-
*
|
|
480
|
-
* @param {number} max - The max count of words will be found
|
|
481
|
-
* @param isAllWhenEmptyPrefix - If true, when the prefix provided as '', returns all the words in the trie.
|
|
482
|
-
* @returns {string[]} an array of strings.
|
|
492
|
+
* Collect words under a prefix up to a maximum count.
|
|
493
|
+
* @remarks Time O(K·L), Space O(K·L)
|
|
494
|
+
* @param [prefix] - Prefix to match; default empty string for root.
|
|
495
|
+
* @param [max] - Maximum number of words to return; default is Number.MAX_SAFE_INTEGER.
|
|
496
|
+
* @param [isAllWhenEmptyPrefix] - When true, collect from root even if prefix is empty.
|
|
497
|
+
* @returns Array of collected words (at most max).
|
|
483
498
|
*/
|
|
499
|
+
|
|
484
500
|
getWords(prefix = '', max = Number.MAX_SAFE_INTEGER, isAllWhenEmptyPrefix = false): string[] {
|
|
485
501
|
prefix = this._caseProcess(prefix);
|
|
486
502
|
const words: string[] = [];
|
|
@@ -508,7 +524,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
508
524
|
if (nodeC) {
|
|
509
525
|
startNode = nodeC;
|
|
510
526
|
} else {
|
|
511
|
-
// Early return if the whole prefix is not found
|
|
512
527
|
return [];
|
|
513
528
|
}
|
|
514
529
|
}
|
|
@@ -520,33 +535,27 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
520
535
|
}
|
|
521
536
|
|
|
522
537
|
/**
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
* The `clone` function returns a new instance of the Trie class with the same values and case
|
|
527
|
-
* sensitivity as the original Trie.
|
|
528
|
-
* @returns A new instance of the Trie class is being returned.
|
|
538
|
+
* Deep clone this trie by iterating and inserting all words.
|
|
539
|
+
* @remarks Time O(ΣL), Space O(ΣL)
|
|
540
|
+
* @returns A new trie with the same words and options.
|
|
529
541
|
*/
|
|
530
|
-
|
|
531
|
-
|
|
542
|
+
|
|
543
|
+
clone(): this {
|
|
544
|
+
const next = this._createInstance();
|
|
545
|
+
for (const x of this) next.add(x);
|
|
546
|
+
return next;
|
|
532
547
|
}
|
|
533
548
|
|
|
534
549
|
/**
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
* @param predicate - The `predicate` parameter is a callback function that takes three arguments:
|
|
541
|
-
* `word`, `index`, and `this`. It should return a boolean value indicating whether the current
|
|
542
|
-
* element should be included in the filtered results or not.
|
|
543
|
-
* @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
|
|
544
|
-
* specify the value of `this` within the `predicate` function. It is used when you want to bind a
|
|
545
|
-
* specific object as the context for the `predicate` function. If `thisArg` is provided, it will be
|
|
546
|
-
* @returns The `filter` method is returning an array of strings (`string[]`).
|
|
550
|
+
* Filter words into a new trie of the same class.
|
|
551
|
+
* @remarks Time O(ΣL), Space O(ΣL)
|
|
552
|
+
* @param predicate - Predicate (word, index, trie) → boolean to keep word.
|
|
553
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
554
|
+
* @returns A new trie containing words that satisfy the predicate.
|
|
547
555
|
*/
|
|
548
|
-
|
|
549
|
-
|
|
556
|
+
|
|
557
|
+
filter(predicate: ElementCallback<string, R, boolean>, thisArg?: any): this {
|
|
558
|
+
const results = this._createInstance();
|
|
550
559
|
let index = 0;
|
|
551
560
|
for (const word of this) {
|
|
552
561
|
if (predicate.call(thisArg, word, index, this)) {
|
|
@@ -557,45 +566,105 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
557
566
|
return results;
|
|
558
567
|
}
|
|
559
568
|
|
|
569
|
+
map<RM>(callback: ElementCallback<string, R, string>, options?: TrieOptions<RM>, thisArg?: any): Trie<RM>;
|
|
570
|
+
|
|
560
571
|
/**
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
*
|
|
566
|
-
* @param
|
|
567
|
-
*
|
|
568
|
-
* @
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
* in which the callback function will be executed. If `thisArg` is provided, it will be used as the
|
|
575
|
-
* value of
|
|
576
|
-
* @returns a new Trie object.
|
|
577
|
-
*/
|
|
578
|
-
map<RM>(
|
|
579
|
-
callback: ElementCallback<string, R, string>,
|
|
580
|
-
toElementFn?: (rawElement: RM) => string,
|
|
572
|
+
* Map words into a new trie (possibly different record type).
|
|
573
|
+
* @remarks Time O(ΣL), Space O(ΣL)
|
|
574
|
+
* @template EM
|
|
575
|
+
* @template RM
|
|
576
|
+
* @param callback - Mapping function (word, index, trie) → newWord (string).
|
|
577
|
+
* @param [options] - Options for the output trie (e.g., toElementFn, caseSensitive).
|
|
578
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
579
|
+
* @returns A new Trie constructed from mapped words.
|
|
580
|
+
*/
|
|
581
|
+
|
|
582
|
+
map<EM, RM>(
|
|
583
|
+
callback: ElementCallback<string, R, EM>,
|
|
584
|
+
options?: TrieOptions<RM>,
|
|
581
585
|
thisArg?: any
|
|
582
|
-
):
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
586
|
+
): IterableElementBase<EM, RM>;
|
|
587
|
+
|
|
588
|
+
map<EM, RM>(callback: ElementCallback<string, R, EM>, options?: TrieOptions<RM>, thisArg?: any): any {
|
|
589
|
+
const newTrie = this._createLike<RM>([], options);
|
|
590
|
+
let i = 0;
|
|
591
|
+
for (const x of this) {
|
|
592
|
+
const v = thisArg === undefined ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);
|
|
593
|
+
if (typeof v !== 'string') {
|
|
594
|
+
throw new TypeError(`Trie.map callback must return string; got ${typeof v}`);
|
|
595
|
+
}
|
|
596
|
+
newTrie.add(v);
|
|
588
597
|
}
|
|
589
598
|
return newTrie;
|
|
590
599
|
}
|
|
591
600
|
|
|
592
601
|
/**
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
*
|
|
597
|
-
*
|
|
602
|
+
* Map words into a new trie of the same element type.
|
|
603
|
+
* @remarks Time O(ΣL), Space O(ΣL)
|
|
604
|
+
* @param callback - Mapping function (word, index, trie) → string.
|
|
605
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
606
|
+
* @returns A new trie with mapped words.
|
|
607
|
+
*/
|
|
608
|
+
|
|
609
|
+
mapSame(callback: ElementCallback<string, R, string>, thisArg?: any): this {
|
|
610
|
+
const next = this._createInstance();
|
|
611
|
+
let i = 0;
|
|
612
|
+
for (const key of this) {
|
|
613
|
+
const mapped = thisArg === undefined ? callback(key, i++, this) : callback.call(thisArg, key, i++, this);
|
|
614
|
+
next.add(mapped);
|
|
615
|
+
}
|
|
616
|
+
return next;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* (Protected) Create an empty instance of the same concrete class.
|
|
621
|
+
* @remarks Time O(1), Space O(1)
|
|
622
|
+
* @param [options] - Options forwarded to the constructor.
|
|
623
|
+
* @returns An empty like-kind trie instance.
|
|
598
624
|
*/
|
|
625
|
+
|
|
626
|
+
protected _createInstance(options?: TrieOptions<R>): this {
|
|
627
|
+
const Ctor: any = this.constructor;
|
|
628
|
+
const next: any = new Ctor([], {
|
|
629
|
+
toElementFn: this.toElementFn,
|
|
630
|
+
caseSensitive: this.caseSensitive,
|
|
631
|
+
...(options ?? {})
|
|
632
|
+
});
|
|
633
|
+
return next as this;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* (Protected) Create a like-kind trie and seed it from an iterable.
|
|
638
|
+
* @remarks Time O(ΣL), Space O(ΣL)
|
|
639
|
+
* @template RM
|
|
640
|
+
* @param [elements] - Iterable used to seed the new trie.
|
|
641
|
+
* @param [options] - Options forwarded to the constructor.
|
|
642
|
+
* @returns A like-kind Trie instance.
|
|
643
|
+
*/
|
|
644
|
+
|
|
645
|
+
protected _createLike<RM>(elements: Iterable<string> | Iterable<RM> = [], options?: TrieOptions<RM>): Trie<RM> {
|
|
646
|
+
const Ctor: any = this.constructor;
|
|
647
|
+
return new Ctor(elements, options) as Trie<RM>;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* (Protected) Spawn an empty like-kind trie instance.
|
|
652
|
+
* @remarks Time O(1), Space O(1)
|
|
653
|
+
* @template RM
|
|
654
|
+
* @param [options] - Options forwarded to the constructor.
|
|
655
|
+
* @returns An empty like-kind Trie instance.
|
|
656
|
+
*/
|
|
657
|
+
|
|
658
|
+
protected _spawnLike<RM>(options?: TrieOptions<RM>): Trie<RM> {
|
|
659
|
+
return this._createLike<RM>([], options);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* (Protected) Iterate all words in lexicographic order of edges.
|
|
664
|
+
* @remarks Time O(ΣL), Space O(H)
|
|
665
|
+
* @returns Iterator of words.
|
|
666
|
+
*/
|
|
667
|
+
|
|
599
668
|
protected *_getIterator(): IterableIterator<string> {
|
|
600
669
|
function* _dfs(node: TrieNode, path: string): IterableIterator<string> {
|
|
601
670
|
if (node.isEnd) {
|
|
@@ -609,20 +678,16 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
609
678
|
yield* _dfs(this.root, '');
|
|
610
679
|
}
|
|
611
680
|
|
|
612
|
-
protected get _total() {
|
|
613
|
-
return this._size;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
681
|
/**
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
* @
|
|
621
|
-
* @protected
|
|
682
|
+
* (Protected) Normalize a string according to case sensitivity.
|
|
683
|
+
* @remarks Time O(L), Space O(L)
|
|
684
|
+
* @param str - Input string to normalize.
|
|
685
|
+
* @returns Normalized string based on caseSensitive.
|
|
622
686
|
*/
|
|
687
|
+
|
|
623
688
|
protected _caseProcess(str: string) {
|
|
624
689
|
if (!this._caseSensitive) {
|
|
625
|
-
str = str.toLowerCase();
|
|
690
|
+
str = str.toLowerCase();
|
|
626
691
|
}
|
|
627
692
|
return str;
|
|
628
693
|
}
|