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

150
LINES

< > BotCompany Repo | #1000859 // Trie - too wasteful if you use unicode

JavaX fragment (include)

1  
/**
2  
 * A character tree map.
3  
 */
4  
static class Trie<T> {
5  
  private final char start;
6  
  private final Trie<T>[] arr;
7  
  public final T value;
8  
9  
  private Trie(char start, Trie<T>[] arr, @Nullable T value) {
10  
    this.start = start;
11  
    this.arr = arr;
12  
    this.value = value;
13  
  }
14  
15  
  @Nullable Trie<T> get(char ch) {
16  
    int i = ch - start;
17  
    return 0 <= i && i < arr.length ? arr[i] : null;
18  
  }
19  
20  
  @Nullable Trie<T> getIgnoreCase(char ch) {
21  
    int i = lower(ch) - start;
22  
    return 0 <= i && i < arr.length ? arr[i] : null;
23  
  }
24  
25  
  /**
26  
   * Returns the value corresponding to s[off:end].
27  
   */
28  
  @Nullable T get(String s, int off, int end) {
29  
    Trie<T> t = this;
30  
    while (off < end) {
31  
      t = t.get(s.charAt(off++));
32  
      if (t == null) { return null; }
33  
    }
34  
    return t.value;
35  
  }
36  
37  
  @Nullable T get(char[] s, int off, int end) {
38  
    Trie<T> t = this;
39  
    while (off < end) {
40  
      t = t.get(s[off++]);
41  
      if (t == null) { return null; }
42  
    }
43  
    return t.value;
44  
  }
45  
46  
  /**
47  
   * Returns the value corresponding to s[off:end] ignoring the case of ASCII
48  
   * characters and matching only against lowercase keys.
49  
   */
50  
  @Nullable T getIgnoreCase(String s, int off, int end) {
51  
    Trie<T> t = this;
52  
    while (off < end) {
53  
      t = t.getIgnoreCase(s.charAt(off++));
54  
      if (t == null) { return null; }
55  
    }
56  
    return t.value;
57  
  }
58  
59  
  @Nullable T getIgnoreCase(char[] s, int off, int end) {
60  
    Trie<T> t = this;
61  
    while (off < end) {
62  
      t = t.getIgnoreCase(s[off++]);
63  
      if (t == null) { return null; }
64  
    }
65  
    return t.value;
66  
  }
67  
68  
  @Override
69  
  public String toString() {
70  
    StringBuilder sb = new StringBuilder();
71  
    toString(sb, 0);
72  
    return sb.toString();
73  
  }
74  
75  
  private void toString(StringBuilder sb, int depth) {
76  
    sb.append(value).append(" {");
77  
    ++depth;
78  
    for (int i = 0; i < arr.length; ++i) {
79  
      if (arr[i] == null) { continue; }
80  
      sb.append('\n');
81  
      for (int j = depth; --j >= 0;) { sb.append("  "); }
82  
      sb.append('\'').append((char) (i + start)).append("':");
83  
      arr[i].toString(sb, depth);
84  
    }
85  
    sb.append("}");
86  
  }
87  
88  
  static <A> Builder<A> builder() { return new Builder<A>(null, (char) 0); }
89  
90  
  static final class Builder<A> {
91  
    A value;
92  
    final char ch;
93  
    final List<Builder<A>> children = new ArrayList<Builder<A>>();
94  
95  
    Builder(@Nullable A value, char ch) {
96  
      this.value = value;
97  
      this.ch = ch;
98  
    }
99  
100  
    Builder<A> put(String s, @Nullable A newValue) {
101  
      put(this, s, newValue);
102  
      return this;
103  
    }
104  
105  
    static <A> void put(Builder<A> b, String s, @Nullable A newValue) {
106  
      for (int i = 0, n = s.length(); i < n; ++i) {
107  
        char ch = s.charAt(i);
108  
        Builder<A> next = null;
109  
        for (Builder<A> child : b.children) {
110  
          if (child.ch == ch) {
111  
            next = child;
112  
            break;
113  
          }
114  
        }
115  
        if (next == null) {
116  
          next = new Builder<A>(null, ch);
117  
          b.children.add(next);
118  
        }
119  
        b = next;
120  
      }
121  
      b.value = newValue;
122  
    }
123  
124  
    @SuppressWarnings("unchecked")
125  
    Trie<A> build() {
126  
      Trie<A>[] arr;
127  
      int n = children.size();
128  
      char min = 0;
129  
      if (n == 0) {
130  
        arr = (Trie<A>[]) NO_TRIES;
131  
      } else {
132  
        Collections.sort(children, new Comparator<Builder<?>>() {
133  
            public int compare(Builder<?> a, Builder<?> b) {
134  
              return a.ch - b.ch;
135  
            }
136  
          });
137  
        min = children.get(0).ch;
138  
        int max = children.get(n-1).ch;
139  
        arr = (Trie<A>[]) new Trie<?>[max - min + 1];
140  
        for (int i = 0; i < n; ++i) {
141  
          Builder<A> b = children.get(i);
142  
          arr[b.ch - min] = b.build();
143  
        }
144  
      }
145  
      return new Trie<A>(min, arr, value);
146  
    }
147  
  }
148  
149  
  private static final Trie<?>[] NO_TRIES = new Trie<?>[0];
150  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1000859
Snippet name: Trie - too wasteful if you use unicode
Eternal ID of this version: #1000859/4
Text MD5: 29bc95ab2f579b872419e09feec5db9d
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2018-04-20 16:13:34
Source code size: 3923 bytes / 150 lines
Pitched / IR pitched: No / No
Views / Downloads: 670 / 806
Version history: 3 change(s)
Referenced in: [show references]