private static void PreAut(char[] x, Graph aut) { int i, state, target, oldTarget, m = x.Length; for (state = Automata.GetInitial(aut), i = 0; i < m; ++i) { oldTarget = Automata.GetTarget(aut, state, x[i]); target = Automata.NewVertex(aut); Automata.SetTarget(aut, state, x[i], target); Automata.CopyVertex(aut, target, oldTarget); state = target; } Automata.SetTerminal(aut, state); }
private static void BuildSuffixAutomaton(char[] x, ref Graph aut) { int i, art, init, last, p, q, r, m = (x.Length - 1); char c; init = Automata.GetInitial(aut); art = Automata.NewVertex(aut); Automata.SetSuffixLink(aut, init, art); last = init; for (i = 0; i < m; ++i) { c = x[i]; p = last; q = Automata.NewVertex(aut); Automata.SetLength(aut, q, Automata.GetLength(aut, p) + 1); Automata.SetPosition(aut, q, Automata.GetPosition(aut, p) + 1); while (p != init && Automata.GetTarget(aut, p, c) == -1) { Automata.SetTarget(aut, p, c, q); Automata.SetShift(aut, p, c, Automata.GetPosition(aut, q) - Automata.GetPosition(aut, p) - 1); p = Automata.GetSuffixLink(aut, p); } if (Automata.GetTarget(aut, p, c) == -1) { Automata.SetTarget(aut, init, c, q); Automata.SetShift(aut, init, c, Automata.GetPosition(aut, q) - Automata.GetPosition(aut, init) - 1); Automata.SetSuffixLink(aut, q, init); } else if (Automata.GetLength(aut, p) + 1 == Automata.GetLength( aut, Automata.GetTarget(aut, p, c))) { Automata.SetSuffixLink(aut, q, Automata.GetTarget(aut, p, c)); } else { r = Automata.NewVertex(aut); Automata.CopyVertex(aut, r, Automata.GetTarget(aut, p, c)); Automata.SetLength(aut, r, Automata.GetLength(aut, p) + 1); Automata.SetSuffixLink(aut, Automata.GetTarget(aut, p, c), r); Automata.SetSuffixLink(aut, q, r); while (p != art && Automata.GetLength(aut, Automata .GetTarget(aut, p, c)) >= Automata.GetLength( aut, r)) { Automata.SetShift(aut, p, c, Automata.GetPosition(aut, Automata.GetTarget(aut, p, c)) - Automata.GetPosition(aut, p) - 1); Automata.SetTarget(aut, p, c, r); p = Automata.GetSuffixLink(aut, p); } } last = q; } Automata.SetTerminal(aut, last); while (last != init) { last = Automata.GetSuffixLink(aut, last); Automata.SetTerminal(aut, last); } }