You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel/Services/Trees/DSA.cs

192 lines
5.0 KiB

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<char, State> _transtions;
public State()
{
_is_teminate = false;
_transtions = new Dictionary<char, State>(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<string> 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<char, State>();
}
public void Reverse(State head)
{
var path = new Stack<Tuple<char, bool>>();
foreach (var s in _transtions)
{
s.Value.Forward(head, s.Key, path);
}
}
private void Forward(State head, char ch, Stack<Tuple<char, bool>> 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<Tuple<char, bool>> 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<string> 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);*/
}
}
}

Powered by TurnKey Linux.