public static void longest_common_substring(SuffixAutomaton sa, char[] a, out int pos, out int len) { pos = 0; len = 0; SuffixAutomaton.Node v = sa.t0; int l = 0; for (int u = 0; u < a.Length; u++) { while (v != sa.t0 && !v.ContainsKeyNext(a[u])) { v = v.link; l = v.len; } if (v.ContainsKeyNext(a[u])) { v = v.GetNext(a[u]); l++; } if (l > len) { len = l; pos = u; } } }
// ----- Suffix Automato Hacks ----------------------------------------- // // Dependencies: // -- Suffix Automaton // // bool find_substring(SuffixAutomaton sa, char[] a) // void longest_common_substring(SuffixAutomaton sa, char[] a, out int pos, out int len) // long number_of_different_substrings(char[] s) // long total_length_of_different_substrings(char[] s) // char[] least_cyclic_shift(char[] s) // --------------------------------------------------------------------- // bool test_find_substring(char[] s, char[] a) // void test_longest_common_substring(char[] s, char[] a, out int pos, out int len) // long test_number_of_different_substrings(char[] s) // long test_total_length_of_different_substrings(char[] s) // char[] test_least_cyclic_shift(char[] s) // --------------------------------------------------------------------- public static bool find_substring(SuffixAutomaton sa, char[] a) { SuffixAutomaton.Node v = sa.t0; foreach (char c in a) { if (!v.ContainsKeyNext(c)) { return(false); } v = v.GetNext(c); } return(true); }
public static char[] least_cyclic_shift(char[] s) { char[] ss = new char[s.Length * 2]; Buffer.BlockCopy(s, 0, ss, 0, sizeof(char) * s.Length); Buffer.BlockCopy(s, 0, ss, sizeof(char) * s.Length, sizeof(char) * s.Length); SuffixAutomaton sa = SuffixAutomaton.Build(ss); if (!sa.lexsorted) { sa.LexSort(); } SuffixAutomaton.Node v = sa.t0; char[] a = new char[s.Length]; int ix = 0; while (ix < s.Length) { v = v.next[0]; a[ix++] = v.key; } return(a); }