using System; using System.Collections.Generic; using System.Text; using System.Threading; using ZeroLevel.Services.Serialization; namespace ZeroLevel.Services.Trees { public class State : IBinarySerializable { private bool _is_teminate; private Dictionary _transtions; public State() { _is_teminate = false; _transtions = new Dictionary(32); } public bool Append(string word, int position) { if (word.Length == position) { if (_is_teminate) { return false; } _is_teminate = true; return true; } State next; if (_transtions.TryGetValue(word[position], out next) == false) { next = new State(); _transtions[word[position]] = next; } return next.Append(word, position + 1); } public bool Contains(string w, int position) { if (w.Length == position) return _is_teminate; State next; if (_transtions.TryGetValue(w[position], out next)) { return next.Contains(w, position + 1); } return false; } public IEnumerable Iterator(StringBuilder sb) { if (_is_teminate) { yield return sb.ToString(); } foreach (var s in _transtions) { sb.Append(s.Key); foreach (var t in s.Value.Iterator(sb)) { yield return t; } sb.Remove(sb.Length - 1, 1); } } public void Serialize(IBinaryWriter writer) { writer.WriteBoolean(this._is_teminate); writer.WriteDictionary(this._transtions); } public void Deserialize(IBinaryReader reader) { _transtions.Clear(); this._is_teminate = reader.ReadBoolean(); this._transtions = reader.ReadDictionary(); } public void Reverse(State head) { var path = new Stack>(); foreach (var s in _transtions) { s.Value.Forward(head, s.Key, path); } } private void Forward(State head, char ch, Stack> path) { path.Push(Tuple.Create(ch, _is_teminate)); if (_is_teminate) { Backward(head, path); } foreach (var s in _transtions) { s.Value.Forward(head, s.Key, path); } path.Pop(); } private void Backward(State head, Stack> path) { State current = head; foreach (var pair in path) { if (false == current._transtions.ContainsKey(pair.Item1)) { var next = new State(); current._transtions.Add(pair.Item1, next); current = next; } else { current = current._transtions[pair.Item1]; } } current._is_teminate = true; } } public class DSA : IBinarySerializable { private State _initialState; private long _count = 0; public long Count => _count; public DSA() { _initialState = new State(); } public bool AppendWord(string word) { if (string.IsNullOrEmpty(word)) return false; if (_initialState.Append(word, 0)) { Interlocked.Increment(ref _count); return true; } return false; } public bool Contains(string word) { return _initialState.Contains(word, 0); } public void Deserialize(IBinaryReader reader) { this._count = reader.ReadLong(); _initialState.Deserialize(reader); } public void Serialize(IBinaryWriter writer) { writer.WriteLong(this._count); _initialState.Serialize(writer); } public IEnumerable Iterator() { return _initialState.Iterator(new StringBuilder()); } public void Reverse() { var reverse_initial = new State(); _initialState.Reverse(reverse_initial); _initialState = reverse_initial; } public void Optimize() { // merge // reverse // merge // reverse /*var reverse_initial = new State(); _initialState.Reverse(reverse_initial); _initialState = new State(); reverse_initial.Reverse(_initialState);*/ } } }