import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class Code_AC1 {
public static class Node{
public String end;
public boolean endUse;
public Node fail;
public Node[] nexts;
public Node(){
endUse = false;
end = null;
fail = null;
nexts = new Node[26];
}
}
public static class ACAutomatic{
private Node root;
public ACAutomatic(){
root = new Node();
}
// 建立前缀树
public void insert(String s){
char[] str = s.toCharArray();
Node cur = root;
int index = 0;
for (int i = 0; i < str.length; i++) {
index = str[i] - 'a';
if(cur.nexts[index] == null){
Node next = new Node();
cur.nexts[index] = next;
}
cur = cur.nexts[index];
}
cur.end = s;
}
public void build(){
// 对树进行宽度优先遍历
Queue<Node> queue = new LinkedList<>();
queue.add(root);
Node cur = null;
Node cfail = null;
while(!queue.isEmpty()){
cur = queue.poll();
for (int i = 0; i < 26; i++) {// 所有的路
// cur -> 父亲 i号儿子,必须把i号儿子的fail指针设置好!
if(cur.nexts[i] != null){
cfail = cur.fail;
cur.nexts[i].fail = root;
while(cfail != null){
if(cfail.nexts[i] != null){
cur.nexts[i].fail = cfail.nexts[i];
break;
}
cfail = cfail.fail;
}
queue.add(cur.nexts[i]);
}
}
}
}
public List<String> containWords(String content){
char[] str = content.toCharArray();
Node cur = root;
Node follow = null;
int index = 0;
List<String> ans = new ArrayList<>();
for (int i = 0; i < str.length; i++) {
index = str[i] - 'a';
// 如果当前字符在这条路上没配出来,就随着fail方向走向下条路径
while(cur.nexts[index] == null && cur != root){
cur = cur.fail;
}
cur = cur.nexts[index] != null ? cur.nexts[index] : root;
follow = cur;
while(follow != root){
if(follow.endUse){
break;
}
if(follow.end != null){
ans.add(follow.end);
follow.endUse = true;
}
follow = follow.fail;
}
}
return ans;
}
}
public static void main(String[] args) {
ACAutomatic ac = new ACAutomatic();
ac.insert("dhe");
ac.insert("he");
ac.insert("abcdheks");
// 设置fail指针
ac.build();
List<String> contains = ac.containWords("dhe");
for (String word : contains) {
System.out.println(word);
}
}
}
数据结构与算法-ac自动机
最新推荐文章于 2025-06-06 22:43:26 发布