Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

120
LINES

< > BotCompany Repo | #1030153 // StringTrie

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (3229L/19K).

1  
// A = type of value in nodes.
2  
// Can be case-sensitive or case-insensitive
3  
// values can't be null
4  
sclass StringTrie<A> {
5  
  A value;
6  
  TreeMap<S, StringTrie<A>> children;
7  
  
8  
  *() {}
9  
  *(A *value) {}
10  
  *(Iterable<S> strings) { addAll(strings, null); } // give all leaves null values
11  
  
12  
  void makeCaseInsensitive() {
13  
    children = asCIMap(children);
14  
  }
15  
  
16  
  bool isCaseInsensitive() {
17  
    ret isCIMap(children);
18  
  }
19  
  
20  
  void addAll(Iterable<S> strings, A value) {
21  
    fOr (S s : strings)
22  
      add(s, value);
23  
  }
24  
  
25  
  void put(S string, A value) { add(string, value); }
26  
  
27  
  void add(S string, A value) {
28  
    ifdef StringTrie_debug printFunctionCall("StringTrie add", string, value); endifdef
29  
    // case 1: empty string
30  
    if (empty(string)) ret with this.value = value;
31  
    
32  
    // case 2: some prefix of new string exists
33  
    S existingPrefix = longestLocalPrefix(string);
34  
      
35  
    ifdef StringTrie_debug print(+existingPrefix); endifdef
36  
    if (nempty(existingPrefix)) {
37  
      StringTrie<A> child = children.get(existingPrefix);
38  
      S substring = substring(string, l(existingPrefix));
39  
      
40  
      // case 2a: new string is complete suffix of existing child
41  
      ifdef StringTrie_debug print(+child); endifdef
42  
      if (child != null)
43  
        ret with child.add(substring, value);
44  
      
45  
      // case 2b: make new branch
46  
      StringTrie<A> branch = newChild(null);
47  
      if (branch.children == null) branch.children = new TreeMap;
48  
      Map.Entry<S, StringTrie<A>> e = children.higherEntry(existingPrefix);
49  
      S key = e.getKey();
50  
      child = e.getValue();
51  
      children.remove(e.getKey());
52  
      children.put(existingPrefix, branch);
53  
      branch.children.put(substring(key, l(existingPrefix)), child);
54  
      branch.children.put(substring, newChild(value));
55  
      ret;
56  
    }
57  
   
58  
    // case 3: no existing prefix, just add new child
59  
    if (children == null) children = new TreeMap;
60  
    children.put(string, newChild(value));
61  
  }
62  
  
63  
  // returns TreeMap or ciMap
64  
  Map<S, A> asMap() {
65  
    Map<S, A> map = isCaseInsensitive() ? ciMap() : new TreeMap;
66  
    new StringBuilder buf;
67  
    collectMap(buf, map);
68  
    ret map;
69  
  }
70  
  
71  
  private void collectMap(StringBuilder buf, Map<S, A> map) {
72  
    if (value != null) map.put(str(buf), value);
73  
    int n = l(buf);
74  
    for (S string, StringTrie<A> child : children) {
75  
      buf.append(string);
76  
      child.collectMap(buf, map);
77  
      buf.setLength(n);
78  
    }
79  
  }
80  
  
81  
  toString {
82  
    new StringBuilder buf;
83  
    if (value != null) {
84  
      buf.append("\"\" => ").append(value).append("\n");
85  
      childrenToString(buf, 2);
86  
    } else
87  
      childrenToString(buf, 0);
88  
    ret str(buf);
89  
  }
90  
  
91  
  void toString(StringBuilder buf, int indent) {
92  
    if (value != null)
93  
      buf.append(" => ").append(value);
94  
    buf.append("\n");
95  
    childrenToString(buf, indent+2);
96  
  }
97  
  
98  
  void childrenToString(StringBuilder buf, int indent) {
99  
    for (S string, StringTrie<A> child : children) {
100  
      buf.append(spaces(indent)).append(quote(string));
101  
      child.toString(buf, indent);
102  
    }
103  
  }
104  
  
105  
  private StringTrie<A> newChild(A value) {
106  
    StringTrie<A> child = new(value);
107  
    if (isCaseInsensitive()) child.makeCaseInsensitive();
108  
    ret child;
109  
  }
110  
  
111  
  S longestLocalPrefix(S string) {
112  
    ret isCaseInsensitive()
113  
      ? longestCommonPrefixOfCISetAndString(string, navigableKeys(children))
114  
      : longestCommonPrefixOfNavigableSetAndString(string, navigableKeys(children));
115  
  }
116  
  
117  
  Set<S> childStrings() { ret keys(children); }
118  
  StringTrie<A> getChild(S string) { ret children.get(string); }
119  
  NavigableMap<S, StringTrie<A>> children() { ret children; }
120  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 5 computer(s): bhatertpkbcr, ekrmjmnbrukm, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1030153
Snippet name: StringTrie
Eternal ID of this version: #1030153/29
Text MD5: 864525b0eaada21cee2cdf106462822a
Transpilation MD5: 785ea2d584e69ea9f47e69fc6380c13e
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-01-13 21:00:58
Source code size: 3729 bytes / 120 lines
Pitched / IR pitched: No / No
Views / Downloads: 287 / 633
Version history: 28 change(s)
Referenced in: [show references]