@lsby/trie-tree 0.0.5 → 0.0.7
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/src/Index.d.ts +9 -28
- package/dist/src/Index.js +70 -113
- package/dist/src/Index.js.map +1 -1
- package/dist/test/index.test.js +5 -3
- package/dist/test/index.test.js.map +1 -1
- package/package.json +8 -3
- package/src/Index.ts +69 -119
- package/test/index.test.ts +6 -3
- package/dist/tools/types/Database.d.ts +0 -23
- package/dist/tools/types/Database.js +0 -3
- package/dist/tools/types/Database.js.map +0 -1
package/dist/src/Index.d.ts
CHANGED
|
@@ -1,29 +1,10 @@
|
|
|
1
|
-
declare
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
declare const 起始子: unique symbol;
|
|
8
|
-
declare type 起始子 = typeof 起始子;
|
|
9
|
-
declare const 节点: unique symbol;
|
|
10
|
-
declare type 节点 = typeof 节点;
|
|
11
|
-
declare type 非空数组<T> = [T, ...T[]];
|
|
12
|
-
export declare type 字典树 = {
|
|
13
|
-
[值]: 起始节点 | 终结节点 | 普通节点;
|
|
14
|
-
};
|
|
15
|
-
declare type 起始节点 = {
|
|
16
|
-
[类型]: 起始子;
|
|
17
|
-
};
|
|
18
|
-
declare type 终结节点 = {
|
|
19
|
-
[类型]: 终结子;
|
|
20
|
-
};
|
|
21
|
-
declare type 普通节点 = {
|
|
22
|
-
[类型]: 节点;
|
|
23
|
-
[当前值]: string;
|
|
24
|
-
[子节点]: 非空数组<普通节点 | 终结节点>;
|
|
25
|
-
};
|
|
1
|
+
export declare class 字典树 {
|
|
2
|
+
private root;
|
|
3
|
+
constructor();
|
|
4
|
+
插入(word: string): void;
|
|
5
|
+
搜索(word: string, 深度?: number): string[];
|
|
6
|
+
}
|
|
26
7
|
export declare function 创建字典树(): 字典树;
|
|
27
|
-
export declare function 插入字典树(
|
|
28
|
-
export declare function 查询字典树(
|
|
29
|
-
export
|
|
8
|
+
export declare function 插入字典树(t: 字典树, s: string): void;
|
|
9
|
+
export declare function 查询字典树(t: 字典树, s: string): string[];
|
|
10
|
+
export declare function 查询字典树_限制深度(t: 字典树, s: string, 深度: number): string[];
|
package/dist/src/Index.js
CHANGED
|
@@ -1,125 +1,82 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.查询字典树 = exports.插入字典树 = exports.创建字典树 = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const 起始子 = Symbol();
|
|
10
|
-
const 节点 = Symbol();
|
|
11
|
-
function 创建字典树() {
|
|
12
|
-
return { [值]: { [类型]: 起始子 } };
|
|
13
|
-
}
|
|
14
|
-
exports.创建字典树 = 创建字典树;
|
|
15
|
-
function 创建字典树节点(字符, 子节点对象) {
|
|
16
|
-
return {
|
|
17
|
-
[类型]: 节点,
|
|
18
|
-
[当前值]: 字符,
|
|
19
|
-
[子节点]: 子节点对象,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
function 创建终结子() {
|
|
23
|
-
return {
|
|
24
|
-
[类型]: 终结子,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
function 取值(a) {
|
|
28
|
-
return a[当前值];
|
|
29
|
-
}
|
|
30
|
-
function 查询字符(a, 字符) {
|
|
31
|
-
var c = a[子节点].filter((a) => a[类型] != 终结子 && 取值(a) == 字符);
|
|
32
|
-
if (c.length == 0)
|
|
33
|
-
return null;
|
|
34
|
-
if (c[0][类型] == 终结子)
|
|
35
|
-
throw new Error('意外的终结子');
|
|
36
|
-
return c[0];
|
|
37
|
-
}
|
|
38
|
-
function 构造链(s) {
|
|
39
|
-
if (s.length == 0)
|
|
40
|
-
throw new Error('不能构造空链');
|
|
41
|
-
var arr = s.split('').reverse();
|
|
42
|
-
var r = 创建终结子();
|
|
43
|
-
for (var a of arr) {
|
|
44
|
-
r = 创建字典树节点(a, [r]);
|
|
3
|
+
exports.查询字典树_限制深度 = exports.查询字典树 = exports.插入字典树 = exports.创建字典树 = exports.字典树 = void 0;
|
|
4
|
+
class 树节点 {
|
|
5
|
+
constructor(key) {
|
|
6
|
+
this.当前字符 = key;
|
|
7
|
+
this.是结尾字符 = false;
|
|
8
|
+
this.子节点 = {};
|
|
45
9
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
10
|
+
枚举所有串(深度 = 0, 当前深度 = 0) {
|
|
11
|
+
if (深度 != 0 && 当前深度 >= 深度) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
if (this.当前字符 == null)
|
|
15
|
+
throw new Error('当前节点为空');
|
|
16
|
+
var 子节点key = Object.keys(this.子节点);
|
|
17
|
+
if (this.是结尾字符 && 子节点key.length == 0) {
|
|
18
|
+
return [this.当前字符];
|
|
19
|
+
}
|
|
20
|
+
if (!this.是结尾字符 && 子节点key.length == 0) {
|
|
21
|
+
throw new Error('非结尾字符必须有子节点');
|
|
22
|
+
}
|
|
23
|
+
var 后续 = 子节点key.map((a) => this.子节点[a].枚举所有串(深度, 当前深度 + 1)).flat();
|
|
24
|
+
if (this.是结尾字符 && 子节点key.length != 0) {
|
|
25
|
+
return [this.当前字符, ...后续.map((a) => this.当前字符 + a)];
|
|
26
|
+
}
|
|
27
|
+
if (!this.是结尾字符 && 子节点key.length != 0) {
|
|
28
|
+
return 后续.map((a) => this.当前字符 + a);
|
|
29
|
+
}
|
|
30
|
+
throw new Error('意外的枚举分支');
|
|
58
31
|
}
|
|
59
|
-
_插入字典树(a[值], s);
|
|
60
32
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return;
|
|
65
|
-
var 第一个字符 = s.substring(0, 1);
|
|
66
|
-
var 剩下的字符串 = s.substring(1);
|
|
67
|
-
var 新子节点 = 查询字符(a, 第一个字符);
|
|
68
|
-
if (新子节点 == null) {
|
|
69
|
-
新子节点 = 构造链(s);
|
|
70
|
-
a[子节点].push(新子节点);
|
|
71
|
-
return;
|
|
33
|
+
class 字典树 {
|
|
34
|
+
constructor() {
|
|
35
|
+
this.root = new 树节点(null);
|
|
72
36
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
37
|
+
插入(word) {
|
|
38
|
+
var node = this.root;
|
|
39
|
+
for (var i = 0; i < word.length; i++) {
|
|
40
|
+
var char = word[i];
|
|
41
|
+
if (!node.子节点[char]) {
|
|
42
|
+
node.子节点[char] = new 树节点(char);
|
|
43
|
+
}
|
|
44
|
+
node = node.子节点[char];
|
|
45
|
+
if (i == word.length - 1) {
|
|
46
|
+
node.是结尾字符 = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
搜索(word, 深度 = 0) {
|
|
51
|
+
var node = this.root;
|
|
52
|
+
var 累计 = [];
|
|
53
|
+
for (var i = 0; i < word.length; i++) {
|
|
54
|
+
var char = word[i];
|
|
55
|
+
if (!node.子节点[char])
|
|
56
|
+
return [];
|
|
57
|
+
累计.push(char);
|
|
58
|
+
node = node.子节点[char];
|
|
59
|
+
}
|
|
60
|
+
var 累计串 = 累计.join('');
|
|
61
|
+
var 累计串减1 = 累计串.substring(0, 累计串.length - 1);
|
|
62
|
+
return node.枚举所有串(深度).map((a) => 累计串减1 + a);
|
|
99
63
|
}
|
|
100
|
-
return a[子节点]
|
|
101
|
-
.map(枚举到终结子)
|
|
102
|
-
.flat()
|
|
103
|
-
.map((x) => a[当前值] + x);
|
|
104
64
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
var 第一个字符 = s.substring(0, 1);
|
|
109
|
-
var 剩下的字符串 = s.substring(1);
|
|
110
|
-
var 命中节点 = 查询字符(a, 第一个字符);
|
|
111
|
-
if (命中节点 == null)
|
|
112
|
-
return [];
|
|
113
|
-
return _查询字典树(命中节点, 剩下的字符串, 累计字符串 + 第一个字符);
|
|
65
|
+
exports.字典树 = 字典树;
|
|
66
|
+
function 创建字典树() {
|
|
67
|
+
return new 字典树();
|
|
114
68
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return _查询字典树(a[值], s);
|
|
69
|
+
exports.创建字典树 = 创建字典树;
|
|
70
|
+
function 插入字典树(t, s) {
|
|
71
|
+
t.插入(s);
|
|
72
|
+
}
|
|
73
|
+
exports.插入字典树 = 插入字典树;
|
|
74
|
+
function 查询字典树(t, s) {
|
|
75
|
+
return t.搜索(s);
|
|
123
76
|
}
|
|
124
77
|
exports.查询字典树 = 查询字典树;
|
|
78
|
+
function 查询字典树_限制深度(t, s, 深度) {
|
|
79
|
+
return t.搜索(s, 深度);
|
|
80
|
+
}
|
|
81
|
+
exports.查询字典树_限制深度 = 查询字典树_限制深度;
|
|
125
82
|
//# sourceMappingURL=Index.js.map
|
package/dist/src/Index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Index.js","sourceRoot":"","sources":["../../src/Index.ts"],"names":[],"mappings":";;;AAAA,MAAM,
|
|
1
|
+
{"version":3,"file":"Index.js","sourceRoot":"","sources":["../../src/Index.ts"],"names":[],"mappings":"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"}
|
package/dist/test/index.test.js
CHANGED
|
@@ -15,14 +15,16 @@ it('测试', function () {
|
|
|
15
15
|
(0, Index_1.插入字典树)(obj, 'ni3');
|
|
16
16
|
(0, Index_1.插入字典树)(obj, 'ni45');
|
|
17
17
|
var c = (0, Index_1.查询字典树)(obj, 'ni');
|
|
18
|
-
断言相等(c, ['ni1', 'ni2', 'ni3', 'ni45']);
|
|
18
|
+
断言相等(c, ['ni', 'ni1', 'ni2', 'ni3', 'ni45']);
|
|
19
19
|
var obj = (0, Index_1.创建字典树)();
|
|
20
20
|
(0, Index_1.插入字典树)(obj, 'n');
|
|
21
|
-
(0, Index_1.插入字典树)(obj, 'ni');
|
|
22
21
|
(0, Index_1.插入字典树)(obj, 'nih');
|
|
23
22
|
(0, Index_1.插入字典树)(obj, 'niha');
|
|
24
23
|
(0, Index_1.插入字典树)(obj, 'nihao');
|
|
25
24
|
var c = (0, Index_1.查询字典树)(obj, 'ni');
|
|
26
|
-
断言相等(c, ['
|
|
25
|
+
断言相等(c, ['nih', 'niha', 'nihao']);
|
|
26
|
+
var obj = (0, Index_1.创建字典树)();
|
|
27
|
+
var c = (0, Index_1.查询字典树)(obj, 'ni');
|
|
28
|
+
断言相等(c, []);
|
|
27
29
|
});
|
|
28
30
|
//# sourceMappingURL=index.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../test/index.test.ts"],"names":[],"mappings":";;AAAA,iBAAc;AACd,wCAAkD;AAElD,SAAS,IAAI,CAAC,CAAM,EAAE,CAAM;IAC1B,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAAE,OAAM;IAClD,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AAClE,CAAC;AAED,EAAE,CAAC,IAAI,EAAE;IACP,IAAI,GAAG,GAAG,IAAA,aAAK,GAAE,CAAA;IACjB,IAAA,aAAK,EAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAChB,IAAA,aAAK,EAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACjB,IAAA,aAAK,EAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACjB,IAAA,aAAK,EAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACjB,IAAA,aAAK,EAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IAClB,IAAI,CAAC,GAAG,IAAA,aAAK,EAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACxB,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../test/index.test.ts"],"names":[],"mappings":";;AAAA,iBAAc;AACd,wCAAkD;AAElD,SAAS,IAAI,CAAC,CAAM,EAAE,CAAM;IAC1B,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAAE,OAAM;IAClD,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AAClE,CAAC;AAED,EAAE,CAAC,IAAI,EAAE;IACP,IAAI,GAAG,GAAG,IAAA,aAAK,GAAE,CAAA;IACjB,IAAA,aAAK,EAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAChB,IAAA,aAAK,EAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACjB,IAAA,aAAK,EAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACjB,IAAA,aAAK,EAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACjB,IAAA,aAAK,EAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IAClB,IAAI,CAAC,GAAG,IAAA,aAAK,EAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACxB,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;IAE5C,IAAI,GAAG,GAAG,IAAA,aAAK,GAAE,CAAA;IACjB,IAAA,aAAK,EAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACf,IAAA,aAAK,EAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACjB,IAAA,aAAK,EAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IAClB,IAAA,aAAK,EAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IACnB,IAAI,CAAC,GAAG,IAAA,aAAK,EAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACxB,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAEjC,IAAI,GAAG,GAAG,IAAA,aAAK,GAAE,CAAA;IACjB,IAAI,CAAC,GAAG,IAAA,aAAK,EAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACxB,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AACb,CAAC,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lsby/trie-tree",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "一个 ts 实现的字典树.",
|
|
5
5
|
"author": "hbybyyang",
|
|
6
6
|
"main": "dist/src/Index.js",
|
|
@@ -23,11 +23,16 @@
|
|
|
23
23
|
"lint-staged": {
|
|
24
24
|
"**/*": "prettier --write --ignore-unknown"
|
|
25
25
|
},
|
|
26
|
-
"dependencies": {},
|
|
27
26
|
"devDependencies": {
|
|
28
27
|
"@types/mocha": "^9.1.0",
|
|
29
|
-
"mocha": "^9.2.2",
|
|
30
28
|
"husky": "^7.0.4",
|
|
29
|
+
"mocha": "^9.2.2",
|
|
30
|
+
"nyc": "^15.1.0",
|
|
31
|
+
"open-cli": "^7.1.0",
|
|
31
32
|
"typescript": "^4.7.4"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/lsby/ts-trie-tree.git"
|
|
32
37
|
}
|
|
33
38
|
}
|
package/src/Index.ts
CHANGED
|
@@ -1,141 +1,91 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
type 非空数组<T> = [T, ...T[]]
|
|
12
|
-
|
|
13
|
-
export type 字典树 = {
|
|
14
|
-
[值]: 起始节点 | 终结节点 | 普通节点
|
|
15
|
-
}
|
|
1
|
+
class 树节点 {
|
|
2
|
+
public 当前字符: string | null
|
|
3
|
+
public 是结尾字符: boolean
|
|
4
|
+
public 子节点: { [key: string]: 树节点 }
|
|
5
|
+
|
|
6
|
+
constructor(key: string | null) {
|
|
7
|
+
this.当前字符 = key
|
|
8
|
+
this.是结尾字符 = false
|
|
9
|
+
this.子节点 = {}
|
|
10
|
+
}
|
|
16
11
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
[类型]: 终结子
|
|
22
|
-
}
|
|
23
|
-
type 普通节点 = {
|
|
24
|
-
[类型]: 节点
|
|
25
|
-
[当前值]: string
|
|
26
|
-
[子节点]: 非空数组<普通节点 | 终结节点>
|
|
27
|
-
}
|
|
12
|
+
枚举所有串(深度: number = 0, 当前深度 = 0): string[] {
|
|
13
|
+
if (深度 != 0 && 当前深度 >= 深度) {
|
|
14
|
+
return []
|
|
15
|
+
}
|
|
28
16
|
|
|
29
|
-
|
|
30
|
-
return { [值]: { [类型]: 起始子 } }
|
|
31
|
-
}
|
|
32
|
-
function 创建字典树节点(字符: string, 子节点对象: 非空数组<普通节点 | 终结节点>): 普通节点 {
|
|
33
|
-
return {
|
|
34
|
-
[类型]: 节点,
|
|
35
|
-
[当前值]: 字符,
|
|
36
|
-
[子节点]: 子节点对象,
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
function 创建终结子(): 终结节点 {
|
|
40
|
-
return {
|
|
41
|
-
[类型]: 终结子,
|
|
42
|
-
}
|
|
43
|
-
}
|
|
17
|
+
if (this.当前字符 == null) throw new Error('当前节点为空')
|
|
44
18
|
|
|
45
|
-
|
|
46
|
-
return a[当前值]
|
|
47
|
-
}
|
|
19
|
+
var 子节点key = Object.keys(this.子节点)
|
|
48
20
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (c[0][类型] == 终结子) throw new Error('意外的终结子')
|
|
53
|
-
return c[0]
|
|
54
|
-
}
|
|
21
|
+
if (this.是结尾字符 && 子节点key.length == 0) {
|
|
22
|
+
return [this.当前字符]
|
|
23
|
+
}
|
|
55
24
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
25
|
+
if (!this.是结尾字符 && 子节点key.length == 0) {
|
|
26
|
+
throw new Error('非结尾字符必须有子节点')
|
|
27
|
+
}
|
|
59
28
|
|
|
60
|
-
|
|
61
|
-
for (var a of arr) {
|
|
62
|
-
r = 创建字典树节点(a, [r])
|
|
63
|
-
}
|
|
29
|
+
var 后续 = 子节点key.map((a) => this.子节点[a].枚举所有串(深度, 当前深度 + 1)).flat()
|
|
64
30
|
|
|
65
|
-
|
|
31
|
+
if (this.是结尾字符 && 子节点key.length != 0) {
|
|
32
|
+
return [this.当前字符, ...后续.map((a) => this.当前字符 + a)]
|
|
33
|
+
}
|
|
66
34
|
|
|
67
|
-
|
|
68
|
-
|
|
35
|
+
if (!this.是结尾字符 && 子节点key.length != 0) {
|
|
36
|
+
return 后续.map((a) => this.当前字符 + a)
|
|
37
|
+
}
|
|
69
38
|
|
|
70
|
-
|
|
71
|
-
if (a[值][类型] == 终结子) throw new Error('不能对终结子插入字符')
|
|
72
|
-
if (a[值][类型] == 起始子) {
|
|
73
|
-
if (s.length == 0) throw new Error('不能对起始子插入空字符串')
|
|
74
|
-
a[值] = 构造链(s)
|
|
75
|
-
return
|
|
39
|
+
throw new Error('意外的枚举分支')
|
|
76
40
|
}
|
|
77
|
-
|
|
78
|
-
_插入字典树(a[值], s)
|
|
79
41
|
}
|
|
80
42
|
|
|
81
|
-
|
|
82
|
-
|
|
43
|
+
export class 字典树 {
|
|
44
|
+
private root: 树节点
|
|
83
45
|
|
|
84
|
-
|
|
85
|
-
|
|
46
|
+
constructor() {
|
|
47
|
+
this.root = new 树节点(null)
|
|
48
|
+
}
|
|
86
49
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
50
|
+
插入(word: string): void {
|
|
51
|
+
var node = this.root
|
|
52
|
+
for (var i = 0; i < word.length; i++) {
|
|
53
|
+
var char = word[i]
|
|
54
|
+
if (!node.子节点[char]) {
|
|
55
|
+
node.子节点[char] = new 树节点(char)
|
|
56
|
+
}
|
|
57
|
+
node = node.子节点[char]
|
|
58
|
+
if (i == word.length - 1) {
|
|
59
|
+
node.是结尾字符 = true
|
|
60
|
+
}
|
|
61
|
+
}
|
|
92
62
|
}
|
|
93
63
|
|
|
94
|
-
|
|
64
|
+
搜索(word: string, 深度: number = 0): string[] {
|
|
65
|
+
var node = this.root
|
|
66
|
+
var 累计: string[] = []
|
|
67
|
+
for (var i = 0; i < word.length; i++) {
|
|
68
|
+
var char = word[i]
|
|
69
|
+
if (!node.子节点[char]) return []
|
|
70
|
+
累计.push(char)
|
|
71
|
+
node = node.子节点[char]
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var 累计串 = 累计.join('')
|
|
75
|
+
var 累计串减1 = 累计串.substring(0, 累计串.length - 1)
|
|
76
|
+
return node.枚举所有串(深度).map((a) => 累计串减1 + a)
|
|
77
|
+
}
|
|
95
78
|
}
|
|
96
79
|
|
|
97
|
-
function
|
|
98
|
-
|
|
99
|
-
if (c.length != 0 && a[子节点].length != 1) return true
|
|
100
|
-
return false
|
|
101
|
-
}
|
|
102
|
-
function 只含有终止子(a: 普通节点): boolean {
|
|
103
|
-
if (a[子节点].length == 1 && a[子节点][0][类型] == 终结子) return true
|
|
104
|
-
return false
|
|
80
|
+
export function 创建字典树() {
|
|
81
|
+
return new 字典树()
|
|
105
82
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (a[类型] == 终结子) return []
|
|
109
|
-
if (只含有终止子(a)) return [a[当前值]]
|
|
110
|
-
if (直接含有终止子和普通节点(a)) {
|
|
111
|
-
return [
|
|
112
|
-
a[当前值],
|
|
113
|
-
...a[子节点]
|
|
114
|
-
.map(枚举到终结子)
|
|
115
|
-
.flat()
|
|
116
|
-
.map((x) => a[当前值] + x),
|
|
117
|
-
]
|
|
118
|
-
}
|
|
119
|
-
return a[子节点]
|
|
120
|
-
.map(枚举到终结子)
|
|
121
|
-
.flat()
|
|
122
|
-
.map((x) => a[当前值] + x)
|
|
83
|
+
export function 插入字典树(t: 字典树, s: string) {
|
|
84
|
+
t.插入(s)
|
|
123
85
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (s.length == 0) return 枚举到终结子(a).map((x) => 累计字符串.substring(0, 累计字符串.length - 1) + x)
|
|
127
|
-
|
|
128
|
-
var 第一个字符 = s.substring(0, 1)
|
|
129
|
-
var 剩下的字符串 = s.substring(1)
|
|
130
|
-
|
|
131
|
-
var 命中节点 = 查询字符(a, 第一个字符)
|
|
132
|
-
if (命中节点 == null) return []
|
|
133
|
-
return _查询字典树(命中节点, 剩下的字符串, 累计字符串 + 第一个字符)
|
|
86
|
+
export function 查询字典树(t: 字典树, s: string) {
|
|
87
|
+
return t.搜索(s)
|
|
134
88
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (s == '') throw new Error('不能查询空字符串')
|
|
138
|
-
if (a[值][类型] == 终结子) throw new Error('不能对终结子查询')
|
|
139
|
-
if (a[值][类型] == 起始子) return []
|
|
140
|
-
return _查询字典树(a[值], s)
|
|
89
|
+
export function 查询字典树_限制深度(t: 字典树, s: string, 深度: number) {
|
|
90
|
+
return t.搜索(s, 深度)
|
|
141
91
|
}
|
package/test/index.test.ts
CHANGED
|
@@ -14,14 +14,17 @@ it('测试', function () {
|
|
|
14
14
|
插入字典树(obj, 'ni3')
|
|
15
15
|
插入字典树(obj, 'ni45')
|
|
16
16
|
var c = 查询字典树(obj, 'ni')
|
|
17
|
-
断言相等(c, ['ni1', 'ni2', 'ni3', 'ni45'])
|
|
17
|
+
断言相等(c, ['ni', 'ni1', 'ni2', 'ni3', 'ni45'])
|
|
18
18
|
|
|
19
19
|
var obj = 创建字典树()
|
|
20
20
|
插入字典树(obj, 'n')
|
|
21
|
-
插入字典树(obj, 'ni')
|
|
22
21
|
插入字典树(obj, 'nih')
|
|
23
22
|
插入字典树(obj, 'niha')
|
|
24
23
|
插入字典树(obj, 'nihao')
|
|
25
24
|
var c = 查询字典树(obj, 'ni')
|
|
26
|
-
断言相等(c, ['
|
|
25
|
+
断言相等(c, ['nih', 'niha', 'nihao'])
|
|
26
|
+
|
|
27
|
+
var obj = 创建字典树()
|
|
28
|
+
var c = 查询字典树(obj, 'ni')
|
|
29
|
+
断言相等(c, [])
|
|
27
30
|
})
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Generated } from 'kysely';
|
|
2
|
-
export default interface Database {
|
|
3
|
-
'学生表': {
|
|
4
|
-
'id': Generated<number>;
|
|
5
|
-
'姓名': string;
|
|
6
|
-
'性别': '男' | '女';
|
|
7
|
-
'所属班级': number;
|
|
8
|
-
'created_at': Generated<string>;
|
|
9
|
-
};
|
|
10
|
-
'班级表': {
|
|
11
|
-
'id': Generated<number>;
|
|
12
|
-
'名称': string;
|
|
13
|
-
'created_at': Generated<string>;
|
|
14
|
-
};
|
|
15
|
-
'kysely_migration': {
|
|
16
|
-
'name': string;
|
|
17
|
-
'timestamp': string;
|
|
18
|
-
};
|
|
19
|
-
'kysely_migration_lock': {
|
|
20
|
-
'id': string;
|
|
21
|
-
'is_locked': Generated<number>;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Database.js","sourceRoot":"","sources":["../../../tools/types/Database.ts"],"names":[],"mappings":""}
|