/// <summary> /// Returns Aho-Corasic tree for a set of patterns and alphabet parameters /// </summary> /// <returns></returns> public static AhoCorasickTree GetAhoCorasickTree(this char[][] patterns, char minChar, char maxChar) { var tree = new AhoCorasickTree(patterns.Sum(p => p.Length) + 1, maxChar - minChar + 1, minChar); foreach (var pattern in patterns) { tree.AddString(pattern); } return(tree); }
/// <summary> /// Counts the number of matchings of patterns in a given text /// tree must be built with a set of distinct patterns! /// </summary> public static long CountMatches(this AhoCorasickTree tree, char[] text) { if (text == null || text.Length == 0) { return(0); } long res = 0; var dp = new int[tree.Size]; dp.Fill(-1); dp[0] = 0; var st = 0; var stack = new int[tree.Size]; int sz = 0; for (int i = 0; i < text.Length; i++) { st = tree.GetNextState(st, (char)(text[i] - tree.MinChar)); int u = st; while (dp[u] == -1) { stack[sz++] = u; u = tree.GetSuffixLink(u); } while (sz > 0) { var cur = stack[--sz]; dp[cur] = (tree.IsLeaf(cur) ? 1 : 0) + dp[u]; u = cur; } res += dp[st]; } return(res); }