多模式匹配AC自动机及其应用
public class AcNode { public char data; public AcNode[] children = new AcNode[26]; // 字符集只包含 a~z 这 26 个字符 public boolean isEndingChar = false; // 结尾字符为 true public int length = -1; // 当 isEndingChar=true 时,记录模式串长度 public AcNode fail; // 失败指针 public AcNode(char data) { this.data = data; } }
class StreamChecker { TrieNode root; TrieNode temp; public StreamChecker(String[] words) { root = new TrieNode(); for (String word : words) { TrieNode cur = root; for (int i = 0; i < word.length(); i++) { int index = word.charAt(i) - 'a'; if (cur.getChild(index) == null) { cur.setChild(index, new TrieNode()); } cur = cur.getChild(index); } cur.setIsEnd(true); } root.setFail(root); Queue<TrieNode> q = new LinkedList<>(); for (int i = 0; i < 26; i++) { if (root.getChild(i) != null) { root.getChild(i).setFail(root); q.add(root.getChild(i)); } else { root.setChild(i, root); } } while (!q.isEmpty()) { TrieNode node = q.poll(); node.setIsEnd(node.getIsEnd() || node.getFail().getIsEnd()); for (int i = 0; i < 26; i++) { if (node.getChild(i) != null) { node.getChild(i).setFail(node.getFail().getChild(i)); q.offer(node.getChild(i)); } else { node.setChild(i, node.getFail().getChild(i)); } } } temp = root; } public boolean query(char letter) { temp = temp.getChild(letter - 'a'); return temp.getIsEnd(); } } class TrieNode { TrieNode[] children; boolean isEnd; //添加失败指针 TrieNode fail; public TrieNode() { children = new TrieNode[26]; } public TrieNode getChild(int index) { return children[index]; } public void setChild(int index, TrieNode node) { children[index] = node; } public boolean getIsEnd() { return isEnd; } public void setIsEnd(boolean b) { isEnd = b; } public TrieNode getFail() { return fail; } public void setFail(TrieNode node) { fail = node; } }
本文来自博客园,作者:邴越,转载请注明原文链接:https://www.cnblogs.com/binyue/p/17353319.html