forked from bicsi/code_snippets
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsuffix_automaton.cpp
More file actions
59 lines (49 loc) · 1.51 KB
/
suffix_automaton.cpp
File metadata and controls
59 lines (49 loc) · 1.51 KB
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
struct SuffixAutomaton {
struct Node {
int link, len;
map<char, int> leg;
};
vector<Node> T;
int last = 0, nodes = 1;
SuffixAutomaton(int sz) {
T.resize(2 * sz + 1);
T[0].link = -1;
T[0].len = 0;
}
// Adds another character to the automaton
int ConsumeChar(char c) {
// Add state for whole string
int cur = nodes++;
T[cur].len = T[last].len + 1;
T[cur].link = 0;
int node = last;
// Add transitions to all suffixes which do not have one already
while (node != -1 && !T[node].leg.count(c)) {
T[node].leg[c] = cur;
node = T[node].link;
}
if (node != -1) {
// We found double-edge
int old = T[node].leg[c];
if (T[old].len == T[node].len + 1) {
// Just set a new link
T[cur].link = old;
} else {
// We have to split one edge
int clone = nodes++;
T[clone].leg = T[old].leg;
T[clone].len = T[node].len + 1;
T[clone].link = T[old].link;
// Set the "good" links
T[old].link = T[cur].link = clone;
// Rewire classes pointing to old
while (node != -1 && T[node].leg[c] == old) {
T[node].leg[c] = clone;
node = T[node].link;
}
}
}
last = cur;
return cur;
}
};