@@ -17,26 +17,20 @@ public class IdentifiersTrie<T> : IDictionary<string, T>
1717
1818 private class TrieNode
1919 {
20- public char charL ;
21- public char charU ;
22- public TrieNode sibl ;
23- public TrieNode next ;
20+ internal char charL ;
21+ internal char charU ;
22+ internal TrieNode sibl ;
23+ internal TrieNode next ;
2424
25- private T _value ;
25+ internal T value ;
2626
27- public T Value
28- {
29- get => _value ;
30- set
31- {
32- HasValue = true ;
33- _value = value ;
34- }
35- }
36-
37- public bool HasValue { get ; private set ; }
38-
39- public TrieNode Find ( char ch )
27+ internal bool hasValue ;
28+
29+ internal TrieNode ( ) { }
30+ internal TrieNode ( char ch )
31+ { charL = char . ToLower ( ch ) ; charU = char . ToUpper ( ch ) ; }
32+
33+ internal TrieNode Find ( char ch )
4034 {
4135 var node = sibl ;
4236 while ( node != null )
@@ -47,47 +41,46 @@ public TrieNode Find(char ch)
4741 }
4842 return null ;
4943 }
50-
51- }
52-
44+ }
45+
5346 public void Add ( string str , T val )
5447 {
5548 var node = _root ;
49+ TrieNode key = node ;
5650 foreach ( char ch in str )
5751 {
58- var key = node . Find ( ch ) ;
59- if ( key == null )
52+ if ( node == null )
6053 {
61- key = new TrieNode
54+ node = new TrieNode ( ch ) ;
55+ key . next = node ;
56+ key = node ;
57+ node = null ;
58+ }
59+ else
60+ {
61+ TrieNode last = node ;
62+ key = node ;
63+ while ( key != null && key . charL != ch && key . charU != ch )
64+ {
65+ last = key ;
66+ key = key . sibl ;
67+ }
68+ if ( key == null )
6269 {
63- charL = char . ToLower ( ch ) ,
64- charU = char . ToUpper ( ch ) ,
65- Value = default ( T ) ,
66- sibl = node . sibl
67- } ;
68- node . sibl = key ;
69- key . next = new TrieNode ( ) ;
70+ key = new TrieNode ( ch ) ;
71+ last . sibl = key ;
72+ }
73+ node = key . next ;
7074 }
71- node = key . next ;
7275 }
7376
74- node . Value = val ;
77+ key . value = val ;
78+ key . hasValue = true ;
7579 }
7680
77- public bool ContainsKey ( string key )
78- {
79- var node = _root ;
80- foreach ( char ch in key )
81- {
82- var keyNode = node . Find ( ch ) ;
83- if ( keyNode == null )
84- {
85- return false ;
86- }
87- node = keyNode . next ;
88- }
89-
90- return node . next == null && node . HasValue ;
81+ public bool ContainsKey ( string str )
82+ {
83+ return TryGetValue ( str , out _ ) ;
9184 }
9285
9386 public bool Remove ( string key )
@@ -96,22 +89,10 @@ public bool Remove(string key)
9689 }
9790
9891 public T Get ( string str )
99- {
100- var node = _root ;
101- foreach ( char ch in str )
102- {
103- TrieNode key = node . Find ( ch ) ;
104- if ( key == null )
105- throw new KeyNotFoundException ( ) ;
106-
107- node = key . next ;
108- }
109-
110- if ( ! node . HasValue )
111- throw new KeyNotFoundException ( ) ;
112-
113- return node . Value ;
114- }
92+ {
93+ return TryGetValue ( str , out var value ) ? value
94+ : throw new KeyNotFoundException ( ) ;
95+ }
11596
11697 public T this [ string index ]
11798 {
@@ -124,27 +105,34 @@ public T this[string index]
124105
125106 public bool TryGetValue ( string str , out T value )
126107 {
127- var node = _root ;
108+ TrieNode key = _root ;
109+ var node = key . sibl ;
128110 foreach ( char ch in str )
129- {
130- var key = node . Find ( ch ) ;
131- if ( key == null )
132- {
133- value = default ;
134- return false ;
135- }
136-
111+ {
112+ while ( node != null && node . charL != ch && node . charU != ch )
113+ {
114+ node = node . sibl ;
115+ }
116+ if ( node == null )
117+ {
118+ value = default ;
119+ return false ;
120+ }
121+
122+ key = node ;
137123 node = key . next ;
138124 }
139125
140- if ( ! node . HasValue )
141- {
142- value = default ;
143- return false ;
126+ if ( key . hasValue )
127+ {
128+ value = key . value ;
129+ return true ;
130+ }
131+ else
132+ {
133+ value = default ;
134+ return false ;
144135 }
145-
146- value = node . Value ;
147- return true ;
148136 }
149137
150138 public IEnumerator < KeyValuePair < string , T > > GetEnumerator ( )
0 commit comments