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);
 }
Beispiel #3
0
        public static SuffixAutomaton Build(char[] str)
        {
            int             n  = str.Length;
            SuffixAutomaton sa = new SuffixAutomaton(n);

            sa.len = str.Length;
            Node last = sa.t0;

            foreach (char c in str)
            {
                last = sa.Extend(last, c);
            }
            return(sa);
        }
        public static long number_of_different_substrings(char[] s)
        {
            SuffixAutomaton sa = SuffixAutomaton.Build(s);

            if (!sa.sortedTopologically)
            {
                sa.SortTopologically();
            }
            long[] D = new long[sa.gen];
            for (int i = sa.gen - 1; i >= 0; i--)
            {
                D[i] = 1;
                for (int j = 0; j < sa.nodes[i].np; j++)
                {
                    D[i] += D[sa.nodes[i].next[j].id];
                }
            }
            return(D[0] - 1);
        }
        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);
        }