Libraryless. Click here for Pure Java version (2965L/19K).
1 | // A = type of element in keys. |
2 | // B = type of value in nodes. |
3 | // Can be case-sensitive or case-insensitive |
4 | // values can't be null |
5 | sclass ListTrie<A, B> { |
6 | B value; |
7 | Comparator<A> comparator; |
8 | TreeMap<L<A>, ListTrie<A, B>> children; |
9 | |
10 | *() {} |
11 | *(Comparator<A> *comparator) {} |
12 | |
13 | void add(L<A> string, B value) { |
14 | ifdef ListTrie_debug printFunctionCall("ListTrie add", string, value); endifdef |
15 | // case 1: empty string |
16 | if (empty(string)) ret with this.value = value; |
17 | |
18 | // case 2: some prefix of new string exists |
19 | L<A> existingPrefix = longestCommonPrefixOfNavigableSetAndList(string, navigableKeys(children), comparator); |
20 | |
21 | ifdef ListTrie_debug print(+existingPrefix); endifdef |
22 | if (nempty(existingPrefix)) { |
23 | ListTrie<A, B> child = children.get(existingPrefix); |
24 | L<A> substring = subList(string, l(existingPrefix)); |
25 | |
26 | // case 2a: new string is complete suffix of existing child |
27 | ifdef ListTrie_debug print(+child); endifdef |
28 | if (child != null) |
29 | ret with child.add(substring, value); |
30 | |
31 | // case 2b: make new branch |
32 | ListTrie<A, B> branch = newChild(null); |
33 | Map.Entry<L<A>, ListTrie<A, B>> e = children.higherEntry(existingPrefix); |
34 | L<A> key = e.getKey(); |
35 | child = e.getValue(); |
36 | children.remove(e.getKey()); |
37 | children.put(existingPrefix, branch); |
38 | branch.makeChildren().put(subList(key, l(existingPrefix)), child); |
39 | branch.children.put(substring, newChild(value)); |
40 | ret; |
41 | } |
42 | |
43 | // case 3: no existing prefix, just add new child |
44 | makeChildren().put(string, newChild(value)); |
45 | } |
46 | |
47 | Map<L<A>, B> asMap() { |
48 | Map<L<A>, B> map = new TreeMap(listComparator(comparator)); |
49 | new L<A> buf; |
50 | collectMap(buf, map); |
51 | ret map; |
52 | } |
53 | |
54 | private void collectMap(L<A> buf, Map<L<A>, B> map) { |
55 | if (value != null) map.put(cloneList(buf), value); |
56 | int n = l(buf); |
57 | for (L<A> string, ListTrie<A, B> child : children) { |
58 | buf.addAll(string); |
59 | child.collectMap(buf, map); |
60 | truncateList(buf, n); |
61 | } |
62 | } |
63 | |
64 | toString { |
65 | new StringBuilder buf; |
66 | if (value != null) { |
67 | buf.append("\"\" => ").append(value).append("\n"); |
68 | childrenToString(buf, 2); |
69 | } else |
70 | childrenToString(buf, 0); |
71 | ret str(buf); |
72 | } |
73 | |
74 | void toString(StringBuilder buf, int indent) { |
75 | if (value != null) |
76 | buf.append(" => ").append(value); |
77 | buf.append("\n"); |
78 | childrenToString(buf, indent+2); |
79 | } |
80 | |
81 | void childrenToString(StringBuilder buf, int indent) { |
82 | for (L<A> string, ListTrie<A, B> child : children) { |
83 | buf.append(spaces(indent)).append(string); |
84 | child.toString(buf, indent); |
85 | } |
86 | } |
87 | |
88 | private ListTrie<A, B> newChild(B value) { |
89 | ListTrie<A, B> child = new(comparator); |
90 | child.value = value; |
91 | ret child; |
92 | } |
93 | |
94 | private TreeMap<L<A>, ListTrie<A, B>> makeChildren() { |
95 | if (children == null) children = new TreeMap(listComparator(comparator)); |
96 | ret children; |
97 | } |
98 | |
99 | Set<L<A>> childStrings() { ret keys(children); } |
100 | ListTrie<A, B> getChild(L<A> string) { ret children.get(string); } |
101 | NavigableMap<L<A>, ListTrie<A, B>> children() { ret children; } |
102 | } |
Began life as a copy of #1030153
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt
No comments. add comment
Snippet ID: | #1030167 |
Snippet name: | ListTrie - generalized StringTrie over lists instead of strings |
Eternal ID of this version: | #1030167/10 |
Text MD5: | 3baa3e1bfbc0486c552d6d14142cd527 |
Transpilation MD5: | f41c383355a0604fbd176a068a39b319 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2020-11-12 09:25:41 |
Source code size: | 3264 bytes / 102 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 202 / 467 |
Version history: | 9 change(s) |
Referenced in: | [show references] |