Exemplo n.º 1
0
        /// <summary>
        /// Finds the longest common prefix of the specified key. Sets values of
        /// <see cref="confluxState"/>, <see cref="lastState"/>, <see cref="prefixPath"/> and <see cref="prefixLenght"/>.
        /// <see cref="confluxState"/> gets the first conflux state encountered (null if no such state exists).
        /// <see cref="lastState"/> gets the last state encountered (null if no prefix exists).
        /// <see cref="prefixPath"/> gets the values of the states encountered.
        /// <see cref="prefixLenght"/> gets the lenght of longest common prefix (0 if no prefix exists).
        /// </summary>
        /// <param name="key">The key to search longest common preifix of.</param>
        protected void CommonPrefix(IEnumerable <TKey> key)
        {
            prefixLenght = 0;
            lastState    = instance.Root;
            confluxState = null;
            var confluxFound = false;

            prefixPath = new Stack <IDawgNode <TKey, TValue> >();
            foreach (var k in key)
            {
                //prefix can be continued
                if (lastState.Contains(k))
                {
                    lastState = lastState.Get(k);
                    prefixPath.Push(lastState);
                    //increment prefix lenght
                    prefixLenght++;
                    if (!confluxFound) //if conflux state was not found yet
                    {
                        //if lastState is conflux
                        if (lastState.Children.Count() > 1)
                        {
                            confluxFound = true;
                            confluxState = lastState;
                        }
                    }
                }
                else
                {
                    break;
                }
            }
        }
Exemplo n.º 2
0
 public bool this[IDawgNode <TKey, TValue> state]
 {
     get { return(registred.ContainsKey(state) && registred[state]); }
     set
     {
         if (value)
         {
             if (!registred.ContainsKey(state))
             {
                 registred.Add(state, true);
             }
             else
             {
                 registred[state] = true;
             }
         }
         else
         {
             if (registred.ContainsKey(state))
             {
                 registred.Remove(state);
             }
         }
     }
 }
Exemplo n.º 3
0
 IEnumerable <KeyValuePair <IEnumerable <TKey>, TValue> > Traverse(IDawgNode <TKey, TValue> node, IList <TKey> currentKey)
 {
     while (true)
     {
         if (Root != node)
         {
             //append node key
             currentKey.Add(node.Key);
             //if node has value then return new pair
             if (node.HasValue)
             {
                 yield return(new KeyValuePair <IEnumerable <TKey>, TValue>(currentKey, node.Value));
             }
         }
         if (node.LeftChild != null)
         {
             foreach (var child in Traverse(node.LeftChild, currentKey))
             {
                 yield return(child);
             }
         }
         currentKey.RemoveAt(currentKey.Count - 1);
         if (node.RightSibling != null)
         {
             node = node.RightSibling;
             continue;
         }
         break;
     }
 }
Exemplo n.º 4
0
        protected override void ReplaceOrRegister(IDawgNode <TKey, TValue> state)
        {
            var child = state.Children.Last(); //last child

            if (!Registered[child])
            {
                //if child has children
                if (child.Children.Any())
                {
                    ReplaceOrRegister(child);
                }
                //if such q exist that q is in registry and q == child
                if (registry.ContainsKey(child))
                {
                    //not registered state is replaced by equal registred one
                    //replacement is reference replacement
                    //states are equal, but in .Net world they are different objects
                    state.Remove(child.Key);
                    state.Add(registry[child]);
                }
                else
                {
                    //else this state becomes the registred one,
                    //meaning that it may be used later as a replacement
                    registry.Add(child, child);
                    Registered[child] = true;
                }
            }
        }
Exemplo n.º 5
0
 protected AbstractDacukBuilder()
 {
     registry     = new Dictionary <IDawgNode <TKey, TValue>, IDawgNode <TKey, TValue> >();
     instance     = new Dawg <TKey, TValue>();
     confluxState = null;
     lastState    = null;
     comparer     = null;
     prefixLenght = 0;
     prefixPath   = new Stack <IDawgNode <TKey, TValue> >();
     Registered   = new RegisteredPropertyHandler();
 }
Exemplo n.º 6
0
 /// <summary>
 /// Adds the specified node.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <exception cref="DawgException">When the specified node already exists.</exception>
 public void Add(IDawgNode <TKey, TValue> node)
 {
     if (LeftChild == null)
     {
         LeftChild = node;
     }
     else
     {
         var current = LeftChild;
         if (node.Key.CompareTo(current.Key) < 0)
         {
             node.RightSibling = LeftChild;
             LeftChild         = node;
         }
         else
         {
             if (LeftChild.Key.CompareTo(node.Key) == 0)
             {
                 throw new DawgException("The specified key already exists.");
             }
             var prev = current;
             current = current.RightSibling;
             if (current == null)
             {
                 prev.RightSibling = node;
             }
             else
             {
                 while (current != null && node.Key.CompareTo(current.Key) <= 0)
                 {
                     if (current.Key.CompareTo(node.Key) == 0)
                     {
                         throw new DawgException("The specified key already exists.");
                     }
                     prev    = current;
                     current = current.RightSibling;
                 }
                 node.RightSibling = current;
                 prev.RightSibling = node;
             }
         }
     }
 }
Exemplo n.º 7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:System.Object"/> class.
 /// </summary>
 public EndLinkedDawgNode(TKey key, IDawgNode <TKey, TValue> leftChild,
                          IDawgNode <TKey, TValue> rightSibling, TValue value) :
     base(key, leftChild, rightSibling)
 {
     this.value = value;
 }
Exemplo n.º 8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:System.Object"/> class.
 /// </summary>
 public EndLinkedDawgNode(TKey key, IDawgNode <TKey, TValue> leftChild,
                          IDawgNode <TKey, TValue> rightSibling) : base(key, leftChild, rightSibling)
 {
 }
Exemplo n.º 9
0
 /// <summary>
 /// Replaces or registers newly created state.
 /// </summary>
 /// <param name="state">The state.</param>
 protected abstract void ReplaceOrRegister(IDawgNode <TKey, TValue> state);
Exemplo n.º 10
0
 /// <summary>
 /// Returns a hash code for the specified object.
 /// </summary>
 /// <returns>
 /// A hash code for the specified object.
 /// </returns>
 /// <param name="obj">The <see cref="T:System.Object"/> for which a hash code is to be returned.</param><exception cref="T:System.ArgumentNullException">The type of <paramref name="obj"/> is a reference type and <paramref name="obj"/> is null.</exception>
 public int GetHashCode(IDawgNode <TKey, TValue> obj)
 {
     return(EqualityComparer <object> .Default.GetHashCode(obj));
 }
Exemplo n.º 11
0
 /// <summary>
 /// Determines whether the specified objects are equal.
 /// </summary>
 /// <returns>
 /// true if the specified objects are equal; otherwise, false.
 /// </returns>
 /// <param name="x">The first object of type <paramref name="T"/> to compare.
 /// </param><param name="y">The second object of type <paramref name="T"/> to compare.</param>
 public bool Equals(IDawgNode <TKey, TValue> x, IDawgNode <TKey, TValue> y)
 {
     return(ReferenceEquals(x, y));
 }
Exemplo n.º 12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:System.Object"/> class.
 /// </summary>
 public InnerDawgNode(TKey key, IDawgNode <TKey, TValue> leftChild, IDawgNode <TKey, TValue> rightSibling)
 {
     Key          = key;
     LeftChild    = leftChild;
     RightSibling = rightSibling;
 }
Exemplo n.º 13
0
 internal Dawg(IDawgNode <TKey, TValue> root)
 {
     this.Root = root;
 }
Exemplo n.º 14
0
 protected IEnumerable <KeyValuePair <IEnumerable <TKey>, TValue> > FuzzySearch(IDawgNode <TKey, TValue> node,
                                                                                List <TKey> currentKey, int currentDiff, int maxDiff, TKey[] key, int keyIndex)
 {
     if (currentDiff <= maxDiff)
     {
         if (Root != node)
         {
             //append node key
             currentKey.Add(node.Key);
             //if node has value then return new pair
             if (node.HasValue)
             {
                 yield return(new KeyValuePair <IEnumerable <TKey>, TValue>(currentKey, node.Value));
             }
         }
         if (node.LeftChild != null)
         {
             foreach (var child in FuzzySearch(node.LeftChild, currentKey,
                                               currentDiff + ((keyIndex >= key.Length || key[keyIndex].CompareTo(node.LeftChild.Key) != 0)? 1 : 0),
                                               maxDiff, key, keyIndex + 1))
             {
                 yield return(child);
             }
         }
         currentKey.RemoveAt(currentKey.Count - 1);
         if (node.RightSibling != null)
         {
             foreach (var child in FuzzySearch(node.RightSibling, currentKey,
                                               currentDiff + ((keyIndex >= key.Length || key[keyIndex].CompareTo(node.RightSibling.Key) != 0) ? 1 : 0),
                                               maxDiff, key, keyIndex + 1))
             {
                 yield return(child);
             }
         }
     }
 }