- Notifications
You must be signed in to change notification settings - Fork 366
/
Copy pathAhoCorasick.java
87 lines (70 loc) · 2.64 KB
/
AhoCorasick.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
importjava.util.*;
publicclassAhoCorasick {
// Trie Node Class
staticclassTrieNode {
Map<Character, TrieNode> children = newHashMap<>();
TrieNodefailureLink = null;
List<String> output = newArrayList<>();
}
privateTrieNoderoot = newTrieNode();
// Step 1: Build the Trie
publicvoidaddKeyword(Stringkeyword) {
TrieNodecurrentNode = root;
for (charc : keyword.toCharArray()) {
currentNode = currentNode.children.computeIfAbsent(c, k -> newTrieNode());
}
currentNode.output.add(keyword);
}
// Step 2: Build Failure Links
publicvoidbuildFailureLinks() {
Queue<TrieNode> queue = newLinkedList<>();
root.failureLink = root;
queue.add(root);
while (!queue.isEmpty()) {
TrieNodecurrent = queue.poll();
for (Map.Entry<Character, TrieNode> entry : current.children.entrySet()) {
charc = entry.getKey();
TrieNodechild = entry.getValue();
// Set failure link
TrieNodefailure = current.failureLink;
while (failure != root && !failure.children.containsKey(c)) {
failure = failure.failureLink;
}
if (failure.children.containsKey(c) && failure.children.get(c) != child) {
child.failureLink = failure.children.get(c);
} else {
child.failureLink = root;
}
// Merge output from failure link
child.output.addAll(child.failureLink.output);
queue.add(child);
}
}
}
// Step 3: Search the Text
publicList<String> search(Stringtext) {
List<String> results = newArrayList<>();
TrieNodecurrentNode = root;
for (charc : text.toCharArray()) {
while (currentNode != root && !currentNode.children.containsKey(c)) {
currentNode = currentNode.failureLink;
}
if (currentNode.children.containsKey(c)) {
currentNode = currentNode.children.get(c);
}
// Add matches to results
results.addAll(currentNode.output);
}
returnresults;
}
publicstaticvoidmain(String[] args) {
AhoCorasickac = newAhoCorasick();
ac.addKeyword("he");
ac.addKeyword("she");
ac.addKeyword("hers");
ac.addKeyword("his");
ac.buildFailureLinks();
List<String> matches = ac.search("ushers");
System.out.println("Matches found: " + matches);
}
}