-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsuffix.py
115 lines (100 loc) · 2.59 KB
/
suffix.py
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import graphviz
to = []
lens, link, lasts = [], [], []
small, big = [], []
cur, last = 0, 0
def init():
global to, link, lens, link, lasts, small, big, cur, last
to = []
lens, link, lasts = [], [], []
small, big, = [], []
cur, last = 0, 0
link.append(-1)
lens.append(0)
to.append({})
lasts.append(-1)
small.append("")
big.append("")
def addchar(c):
global to, link, lens, link, lasts, small, big, cur, last
last = cur
cur = len(lens)
lens.append(lens[last]+1)
link.append(0)
small.append("")
lasts.append(last)
to.append({})
big.append(big[last]+c)
p = last
while p >= 0 and c not in to[p]:
to[p][c] = cur;
p = link[p]
if p == -1:
return
q = to[p][c]
if lens[q] == lens[p]+1:
link[cur] = q
else:
clone = len(lens)
lens.append(lens[p]+1)
link.append(link[q])
small.append("")
to.append(to[q].copy())
big.append(big[p]+c)
link[cur],link[q] = clone,clone
lasts.append(p);
while p >= 0 and to[p][c] == q:
to[p][c] = clone
p = link[p]
def insert(s):
init()
for c in s:
addchar(c)
def g_label(u):
if u == 0:
return "0"
global big, small
return big[u]+'\n\n'+small[u]
vis = []
topo = []
def dfs_topo(u):
if vis[u]:
return
vis[u] = True
for c in to[u].keys():
dfs_topo(to[u][c])
topo.append(u)
def dfs(u, graph, show_links):
if vis[u]:
return
vis[u] = True
for c in to[u].keys():
graph.edge(g_label(u), g_label(to[u][c]), label=c)
dfs(to[u][c], graph, show_links)
if link[u] != -1 and show_links:
graph.edge(g_label(u), g_label(link[u]), color='blue', constraint='false')
def gen(s, show_links):
insert(s)
graph = graphviz.Digraph("G", filename="./graph")
graph.attr(rankdir='LR', size='8,5', ordering='out', label="Fig. "+s+"'s suffix automaton")
graph.attr('node', shape='doublecircle', color='red')
global cur, link, big, small, topo
global vis
vis = [False] * len(lens)
topo = []
dfs_topo(0)
topo = topo[::-1]
for u in topo:
for c in to[u]:
v = to[u][c]
if len(small[u])+1 < len(small[v]) or small[v] == "":
small[v] = small[u]+c
while cur > -1:
graph.node(g_label(cur))
cur = link[cur]
graph.node("", shape='none')
graph.edge("", "0")
graph.attr('node', shape='circle', color='black')
vis = [False] * len(lens)
dfs(0, graph, show_links)
graph.render()