/// <summary> /// Searches passed text and returns first occurrence of any keyword /// </summary> /// <param name="text">Text to search</param> /// <returns>First occurrence of any keyword (or StringSearchResult.Empty if text doesn't contain any keyword)</returns> //public StringSearchResult FindFirst(string text) //{ // TreeCharNode ptr = Root; // int index = 0; // while (index < text.Length) // { // TreeCharNode trans = null; // while (trans == null) // { // trans = ptr.Children.ContainsKey(text[index]) ? ptr.Children[text[index]] : null; // if (ptr == Root) // break; // if (trans == null) // ptr = ptr.Failure; // } // if (trans != null) // ptr = trans; // foreach (string found in ptr.Words) // return new StringSearchResult(index - found.Length + 1, found); // index++; // } // return new StringSearchResult(-1, ""); //} /// <summary> /// Searches passed text and returns true if text contains any keyword /// </summary> /// <param name="text">Text to search</param> /// <returns>True when text contains any keyword</returns> public bool ContainsAny(string text) { TreeCharNode ptr = Root; int index = 0; while (index < text.Length) { TreeCharNode trans = null; while (trans == null) { trans = ptr.Children.ContainsKey(text[index]) ? ptr.Children[text[index]] : null; if (ptr == Root) { break; } if (trans == null) { ptr = ptr.Failure; } } if (trans != null) { ptr = trans; } if (ptr.Words.Any()) { return(true); } index++; } return(false); }
/// <summary> /// Searches passed text and returns all occurrences of any keyword /// </summary> /// <param name="text">Text to search</param> /// <returns>Array of occurrences</returns> public List <StringSearchResult> FindAll(string text) { var ret = new List <StringSearchResult>(); TreeCharNode ptr = Root; int index = 0; while (index < text.Length) { TreeCharNode trans = null; while (trans == null) { trans = ptr.Children.ContainsKey(text[index]) ? ptr.Children[text[index]] : null; if (ptr == Root) { break; } if (trans == null) { ptr = ptr.Failure; } } if (trans != null) { ptr = trans; } foreach (string found in ptr.Words) { ret.Add(new StringSearchResult(index - found.Length + 1, found)); } index++; } return(ret); }
private void BuildTree(List <string> words) { Root = new TreeCharNode(' '); foreach (string w in words) { TreeCharNode nd = Root; foreach (char c in w) { TreeCharNode ndNew = null; if (nd.Children.ContainsKey(c)) { ndNew = nd.Children[c]; } if (ndNew == null) { ndNew = new TreeCharNode(c, nd); nd.Children.Add(c, ndNew); } nd = ndNew; } nd.Words.Add(w); } // Find failure functions Queue <TreeCharNode> nodes = new Queue <TreeCharNode>(); // level 1 nodes - fail to root node foreach (TreeCharNode nd in Root.Children.Values) { nd.Failure = Root; foreach (TreeCharNode trans in nd.Children.Values) { nodes.Enqueue(trans); } } // other nodes - using BFS while (nodes.Any()) { TreeCharNode nd = nodes.Dequeue(); TreeCharNode r = nd.Parent.Failure; while (r != null && !r.Children.ContainsKey(nd.Id)) { r = r.Failure; } if (r == null) { nd.Failure = Root; } else { nd.Failure = r.Children[nd.Id]; foreach (string word in nd.Failure.Words) { nd.Words.Add(word); } } foreach (TreeCharNode child in nd.Children.Values) { nodes.Enqueue(child); } } Root.Failure = Root; }
public TreeCharNode(char id, TreeCharNode parent) : this(id) { Parent = parent; }