示例#1
0
        /// <summary>
        /// an attempt to do the forwardonlycursor alg using a stack instead of a queue. is slightly slower. not
        /// the tightest implementation either.
        /// </summary>
        /// <param name="trie"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        public static List <StringSearchMatch> FindMatchesUsingForwardOnlyCursor2(ITrieStructure trie, string text)
        {
            List <StringSearchMatch> rv = new List <StringSearchMatch>();

            if (string.IsNullOrEmpty(text))
            {
                return(rv);
            }

            var maxIndex = text.Length - 1;

            Stack <MatchUoW> bucket = new Stack <MatchUoW>();
            int bucketSize          = 0;

            for (int i = 0; i <= maxIndex; i++)
            {
                //get current char
                char currentChar = text[i];

                //1.  set up new items
                Stack <MatchUoW> newItems = new Stack <MatchUoW>();
                var node = trie.Root[currentChar];
                if (node != null)
                {
                    MatchUoW uow = new MatchUoW(i, currentChar, node);
                    newItems.Push(uow);
                }

                //2.  handle old items
                for (int j = 0; j < bucketSize; j++)
                {
                    var eachOld = bucket.Pop();

                    //if this matches, update the rv
                    var match = eachOld.GetWordMatch();
                    if (match != null)
                    {
                        rv.Add(match);
                    }

                    //can we carry the item over?
                    if (eachOld.MoveNext(currentChar))
                    {
                        newItems.Push(eachOld);
                    }
                }

                bucketSize = newItems.Count;
                for (int j = 0; j < bucketSize; j++)
                {
                    bucket.Push(newItems.Pop());
                }
            }
            return(rv);
        }
示例#2
0
        public static List<StringSearchMatch> FindMatchesUsingForwardOnlyCursor2a(ITrieStructure trie, string text)
        {
            List<StringSearchMatch> rv = new List<StringSearchMatch>();

            if (string.IsNullOrEmpty(text))
                return rv;

            var maxIndex = text.Length - 1;

            Queue<MatchUoW> queue = new Queue<MatchUoW>();

            for (int i = 0; i <= maxIndex; i++)
            {
                //get current char
                char currentChar = text[i];

                //dequeue all carryover items, and identify which ones can continue
                Queue<MatchUoW> reQueuedItems = new Queue<MatchUoW>();
                int queueCount = queue.Count;
                if (queueCount > 0)
                {
                    for (int j = 0; j < queueCount; j++)
                    {
                        MatchUoW dequeueItem = queue.Dequeue();

                        //if this matches, update the rv
                        var match = dequeueItem.GetWordMatch();
                        if (match != null)
                            rv.Add(match);

                        //can we carry the item over?
                        if (dequeueItem.MoveNext(currentChar))
                        {
                            reQueuedItems.Enqueue(dequeueItem);
                        }
                    }

                    //queue up the ones that continue
                    foreach (var each in reQueuedItems)
                        queue.Enqueue(each);
                }


                //Possibly create a unit of work for this particular character (starting from root)
                var node = trie.Root[currentChar];
                if (node == null)
                    continue;

                MatchUoW uow = new MatchUoW(i, currentChar, node);
                queue.Enqueue(uow);
            }
            return rv;
        }
示例#3
0
        /// <summary>
        /// for the provided index position, examines the trie to see if it can handle the character, and moves through
        /// the trie graph until it no longer matches.  returns list to account for situation where matches share a common suffix.
        /// </summary>
        /// <param name="trie"></param>
        /// <param name="idx"></param>
        /// <param name="text"></param>
        /// <param name="graspLengthOUT">the number of characters processed</param>
        /// <returns></returns>
        public static List<StringSearchMatch> FindMatchesAtPosition(ITrieStructure trie, int idx, string text, out int graspLengthOUT)
        {
            List<StringSearchMatch> rv = new List<StringSearchMatch>();
            graspLengthOUT = 0;

            //basic cursor position validation
            int maxIndex = text.Length - 1;

            if (maxIndex < idx)
                return rv;

            graspLengthOUT = 1;//we're at least processing 1 character
            var currentIdx = idx;
            var currentNode = trie.Root;
            var currentChar = text[currentIdx];

            //do the first test in the loop
            currentNode = currentNode[currentChar];
            if (currentNode == null)
                return rv;

            var queue = new Queue<Tuple<int, char, ITrieNode>>();

            //define function to increment position, and update currentIdx, currentChar, and queue it up
            //implicit is the currentNode position has ALREADY been incremented at this point
            Func<bool> enqueue = () =>
            {
                //get the next char
                currentIdx++;
                //validate position
                if (maxIndex < currentIdx)
                    return false;

                currentChar = text[currentIdx];
                queue.Enqueue(new Tuple<int, char, ITrieNode>(currentIdx, currentChar, currentNode));
                return true;
            };

            enqueue();

            while (queue.Count > 0)
            {
                var tuple = queue.Dequeue();
                currentNode = tuple.Item3;
                currentChar = tuple.Item2;
                currentIdx = tuple.Item1;

                //if we're matching, return it
                if (currentNode.HasWord)
                {
                    var match = StringSearchMatch.New(currentIdx - 1 - currentNode.Id.Length, currentNode.Id, currentNode.Value);
                    rv.Add(match);

                    //update grasp length
                    var matchGraspLength = match.Word.Length;
                    if (graspLengthOUT < matchGraspLength)
                        graspLengthOUT = matchGraspLength;
                }

                //does the trie even handle (aka lift, bro) this particular character?
                currentNode = currentNode[currentChar];
                if (currentNode != null)
                {
                    enqueue();
                }
            }

            return rv;
        }
示例#4
0
        /// <summary>
        /// an attempt to do the forwardonlycursor alg using a stack instead of a queue. is slightly slower. not
        /// the tightest implementation either.
        /// </summary>
        /// <param name="trie"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        public static List<StringSearchMatch> FindMatchesUsingForwardOnlyCursor2(ITrieStructure trie, string text)
        {
            List<StringSearchMatch> rv = new List<StringSearchMatch>();

            if (string.IsNullOrEmpty(text))
                return rv;

            var maxIndex = text.Length - 1;

            Stack<MatchUoW> bucket = new Stack<MatchUoW>();
            int bucketSize = 0;

            for (int i = 0; i <= maxIndex; i++)
            {
                //get current char
                char currentChar = text[i];

                //1.  set up new items
                Stack<MatchUoW> newItems = new Stack<MatchUoW>();
                var node = trie.Root[currentChar];
                if (node != null)
                {
                    MatchUoW uow = new MatchUoW(i, currentChar, node);
                    newItems.Push(uow);
                }

                //2.  handle old items
                for (int j = 0; j < bucketSize; j++)
                {
                    var eachOld = bucket.Pop();

                    //if this matches, update the rv
                    var match = eachOld.GetWordMatch();
                    if (match != null)
                        rv.Add(match);

                    //can we carry the item over?
                    if (eachOld.MoveNext(currentChar))
                    {
                        newItems.Push(eachOld);
                    }
                }

                bucketSize = newItems.Count;
                for (int j = 0; j < bucketSize; j++)
                {
                    bucket.Push(newItems.Pop());
                }
            }
            return rv;
        }
示例#5
0
        public static List <StringSearchMatch> FindMatchesUsingForwardOnlyCursor2a(ITrieStructure trie, string text)
        {
            List <StringSearchMatch> rv = new List <StringSearchMatch>();

            if (string.IsNullOrEmpty(text))
            {
                return(rv);
            }

            var maxIndex = text.Length - 1;

            Queue <MatchUoW> queue = new Queue <MatchUoW>();

            for (int i = 0; i <= maxIndex; i++)
            {
                //get current char
                char currentChar = text[i];

                //dequeue all carryover items, and identify which ones can continue
                Queue <MatchUoW> reQueuedItems = new Queue <MatchUoW>();
                int queueCount = queue.Count;
                if (queueCount > 0)
                {
                    for (int j = 0; j < queueCount; j++)
                    {
                        MatchUoW dequeueItem = queue.Dequeue();

                        //if this matches, update the rv
                        var match = dequeueItem.GetWordMatch();
                        if (match != null)
                        {
                            rv.Add(match);
                        }

                        //can we carry the item over?
                        if (dequeueItem.MoveNext(currentChar))
                        {
                            reQueuedItems.Enqueue(dequeueItem);
                        }
                    }

                    //queue up the ones that continue
                    foreach (var each in reQueuedItems)
                    {
                        queue.Enqueue(each);
                    }
                }


                //Possibly create a unit of work for this particular character (starting from root)
                var node = trie.Root[currentChar];
                if (node == null)
                {
                    continue;
                }

                MatchUoW uow = new MatchUoW(i, currentChar, node);
                queue.Enqueue(uow);
            }
            return(rv);
        }
示例#6
0
        /// <summary>
        /// for the provided index position, examines the trie to see if it can handle the character, and moves through
        /// the trie graph until it no longer matches.  returns list to account for situation where matches share a common suffix.
        /// </summary>
        /// <param name="trie"></param>
        /// <param name="idx"></param>
        /// <param name="text"></param>
        /// <param name="graspLengthOUT">the number of characters processed</param>
        /// <returns></returns>
        public static List <StringSearchMatch> FindMatchesAtPosition(ITrieStructure trie, int idx, string text, out int graspLengthOUT)
        {
            List <StringSearchMatch> rv = new List <StringSearchMatch>();

            graspLengthOUT = 0;

            //basic cursor position validation
            int maxIndex = text.Length - 1;

            if (maxIndex < idx)
            {
                return(rv);
            }

            graspLengthOUT = 1;//we're at least processing 1 character
            var currentIdx  = idx;
            var currentNode = trie.Root;
            var currentChar = text[currentIdx];

            //do the first test in the loop
            currentNode = currentNode[currentChar];
            if (currentNode == null)
            {
                return(rv);
            }

            var queue = new Queue <Tuple <int, char, ITrieNode> >();

            //define function to increment position, and update currentIdx, currentChar, and queue it up
            //implicit is the currentNode position has ALREADY been incremented at this point
            Func <bool> enqueue = () =>
            {
                //get the next char
                currentIdx++;
                //validate position
                if (maxIndex < currentIdx)
                {
                    return(false);
                }

                currentChar = text[currentIdx];
                queue.Enqueue(new Tuple <int, char, ITrieNode>(currentIdx, currentChar, currentNode));
                return(true);
            };

            enqueue();

            while (queue.Count > 0)
            {
                var tuple = queue.Dequeue();
                currentNode = tuple.Item3;
                currentChar = tuple.Item2;
                currentIdx  = tuple.Item1;

                //if we're matching, return it
                if (currentNode.HasWord)
                {
                    var match = StringSearchMatch.New(currentIdx - 1 - currentNode.Id.Length, currentNode.Id, currentNode.Value);
                    rv.Add(match);

                    //update grasp length
                    var matchGraspLength = match.Word.Length;
                    if (graspLengthOUT < matchGraspLength)
                    {
                        graspLengthOUT = matchGraspLength;
                    }
                }

                //does the trie even handle (aka lift, bro) this particular character?
                currentNode = currentNode[currentChar];
                if (currentNode != null)
                {
                    enqueue();
                }
            }

            return(rv);
        }