/// <summary> /// Searches the specified text and determines if it contains any occurrence of any keyword. /// </summary> /// <param name="text">The text to search.</param> /// <param name="startIndex">The search starting position.</param> /// <returns> /// <c>true</c> if the text searched contains any occurrence of any keyword; otherwise, <c>false</c>. /// </returns> public bool ContainsAny(string text, int startIndex = 0) { InnerNode ptr = _root; while (startIndex < text.Length) { InnerNode trans = null; while (trans == null) { trans = ptr.GetTransition(text[startIndex]); if (ptr == _root) { break; } if (trans == null) { ptr = ptr._failure; } } if (trans != null) { ptr = trans; } if (ptr._results.Count > 0) { return(true); } ++startIndex; } return(false); }
/// <summary> /// Searches the specified text and returns all occurrences of any keyword. /// </summary> /// <param name="text">The text to search.</param> /// <param name="startIndex">The search starting position.</param> /// <returns> /// An array of <see cref="StringSearchResult" /> objects that store the search result; null if the search fails. /// </returns> public StringSearchResult[] FindAll(string text, int startIndex = 0) { var rlt = new List <StringSearchResult>(); InnerNode ptr = _root; while (startIndex < text.Length) { InnerNode trans = null; while (trans == null) { trans = ptr.GetTransition(text[startIndex]); if (ptr == _root) { break; } if (trans == null) { ptr = ptr._failure; } } if (trans != null) { ptr = trans; } foreach (var found in ptr._results) { rlt.Add(new StringSearchResult() { Position = startIndex - found.Key.Length + 1, Value = found.Key, HitIndex = found.Value }); } ++startIndex; } if (rlt.Count == 0) { return(null); } return(rlt.ToArray()); }
void _buildTree(string[] keywords) { //build keyword tree and transition function _root = new InnerNode(null, ' '); var keywordCount = keywords.Length; for (int i = 0; i < keywordCount; ++i) { var p = keywords[i]; // add pattern to tree InnerNode nd = _root; foreach (var c in p) { InnerNode ndNew = null; foreach (InnerNode trans in nd._transitionsArr) { if (trans._char == c) { ndNew = trans; break; } } if (ndNew == null) { ndNew = new InnerNode(nd, c); nd.AddTransition(ndNew); } nd = ndNew; } nd.AddResult(p, i); } // Find failure functions var nodes = new List <InnerNode>(); // level 1 nodes - fail to root node foreach (InnerNode nd in _root._transitionsArr) { nd._failure = _root; foreach (InnerNode trans in nd._transitionsArr) { nodes.Add(trans); } } // other nodes - using BFS while (nodes.Count != 0) { var newNodes = new List <InnerNode>(); foreach (InnerNode nd in nodes) { InnerNode r = nd._parent._failure; char c = nd._char; while (r != null && !r.ContainsTransition(c)) { r = r._failure; } if (r == null) { nd._failure = _root; } else { nd._failure = r.GetTransition(c); foreach (var result in nd._failure._results) { nd.AddResult(result.Key, result.Value); } } // add child nodes to BFS list foreach (InnerNode child in nd._transitionsArr) { newNodes.Add(child); } } nodes = newNodes; } _root._failure = _root; }