Beispiel #1
0
        public List <StringSearchMatch> FindMatches(string text)
        {
            List <StringSearchMatch> rv = new List <StringSearchMatch>();

            var words = this.Words.Keys.ToArray();

            Parallel.For(0, words.Length - 1,
                         () => new List <StringSearchMatch>(),
                         (x, loop, subList) =>
            {
                var word          = words[x];
                object val        = this.Words[word];
                string searchText = text;

                int idx = searchText.IndexOf(word);

                //search for this
                while (idx > 0)
                {
                    subList.Add(StringSearchMatch.New(idx, word, val));
                    searchText = searchText.Substring(idx + word.Length);
                    idx        = searchText.IndexOf(word);
                }

                return(subList);
            },
                         (x) => { rv.AddRange(x); }
                         );

            return(rv);
        }
Beispiel #2
0
            /// <summary>
            /// if the current node has a word, we build a match to return
            /// </summary>
            /// <returns></returns>
            public StringSearchMatch GetWordMatch()
            {
                if (!this.CurrentNode.HasWord)
                {
                    return(null);
                }

                var match = StringSearchMatch.New(this.StartingIndex, this.CurrentNode.Id, this.CurrentNode.Value);

                return(match);
            }
Beispiel #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);
        }