Libraryless. Click here for Pure Java version (2965L/19K).
// A = type of element in keys. // B = type of value in nodes. // Can be case-sensitive or case-insensitive // values can't be null sclass ListTrie<A, B> { B value; Comparator<A> comparator; TreeMap<L<A>, ListTrie<A, B>> children; *() {} *(Comparator<A> *comparator) {} void add(L<A> string, B value) { ifdef ListTrie_debug printFunctionCall("ListTrie add", string, value); endifdef // case 1: empty string if (empty(string)) ret with this.value = value; // case 2: some prefix of new string exists L<A> existingPrefix = longestCommonPrefixOfNavigableSetAndList(string, navigableKeys(children), comparator); ifdef ListTrie_debug print(+existingPrefix); endifdef if (nempty(existingPrefix)) { ListTrie<A, B> child = children.get(existingPrefix); L<A> substring = subList(string, l(existingPrefix)); // case 2a: new string is complete suffix of existing child ifdef ListTrie_debug print(+child); endifdef if (child != null) ret with child.add(substring, value); // case 2b: make new branch ListTrie<A, B> branch = newChild(null); Map.Entry<L<A>, ListTrie<A, B>> e = children.higherEntry(existingPrefix); L<A> key = e.getKey(); child = e.getValue(); children.remove(e.getKey()); children.put(existingPrefix, branch); branch.makeChildren().put(subList(key, l(existingPrefix)), child); branch.children.put(substring, newChild(value)); ret; } // case 3: no existing prefix, just add new child makeChildren().put(string, newChild(value)); } Map<L<A>, B> asMap() { Map<L<A>, B> map = new TreeMap(listComparator(comparator)); new L<A> buf; collectMap(buf, map); ret map; } private void collectMap(L<A> buf, Map<L<A>, B> map) { if (value != null) map.put(cloneList(buf), value); int n = l(buf); for (L<A> string, ListTrie<A, B> child : children) { buf.addAll(string); child.collectMap(buf, map); truncateList(buf, n); } } toString { new StringBuilder buf; if (value != null) { buf.append("\"\" => ").append(value).append("\n"); childrenToString(buf, 2); } else childrenToString(buf, 0); ret str(buf); } void toString(StringBuilder buf, int indent) { if (value != null) buf.append(" => ").append(value); buf.append("\n"); childrenToString(buf, indent+2); } void childrenToString(StringBuilder buf, int indent) { for (L<A> string, ListTrie<A, B> child : children) { buf.append(spaces(indent)).append(string); child.toString(buf, indent); } } private ListTrie<A, B> newChild(B value) { ListTrie<A, B> child = new(comparator); child.value = value; ret child; } private TreeMap<L<A>, ListTrie<A, B>> makeChildren() { if (children == null) children = new TreeMap(listComparator(comparator)); ret children; } Set<L<A>> childStrings() { ret keys(children); } ListTrie<A, B> getChild(L<A> string) { ret children.get(string); } NavigableMap<L<A>, ListTrie<A, B>> children() { ret children; } }
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: | 203 / 467 |
Version history: | 9 change(s) |
Referenced in: | #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674) |