Example #1
0
        // see pseudocode https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm#Description_of_pseudocode_for_the_search_algorithm
        // \param T is the precomputed lookup table for the search string
        public static int kmpSearch(IStringAccessor <int> S, IStringAccessor <int> W, int[] T, out bool found)
        {
            found = false;

            int m = 0; // the beginning of the current match in S
            int i = 0; // the position of the current character in W

            while (m + i < S.length())
            {
                if (W.at(i) == S.at(m + i))
                {
                    if (i == W.length() - 1)
                    {
                        found = true;
                        return(m);
                    }
                    i++;
                }
                else
                {
                    if (T[i] > -1)
                    {
                        m = m + i - T[i]; i = T[i];
                    }
                    else
                    {
                        m++;
                        i = 0;
                    }
                }
            }

            // if we reach here, we have serched all of S unsuccessfully
            return(-1);
        }
Example #2
0
        // see pseudocode https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm#Description_of_pseudocode_for_the_table-building_algorithm
        // \param W the word to be analyzed
        // \param T the table to be filled
        public static void kmpTable(IStringAccessor <int> W, ref int[] T)
        {
            if (W.length() != T.Length)
            {
                throw new Exception();
            }

            int pos = 2; // the current position we are computing in T
            int cnd = 0; // the zero-based index in W of the next character of the current candidate substring

            // the first few values are fixed but different fro what the algorithm might suggest
            T[0] = -1;
            T[1] = 0;

            while (pos < W.length())
            {
                // first case: the substring continues
                if (W.at(pos - 1) == W.at(cnd))
                {
                    T[pos] = cnd + 1;
                    cnd++;
                    pos++;
                }
                // second case: it doesn't, but we can fall back)
                else if (cnd > 0)
                {
                    cnd = T[cnd];
                }

                // third case: we have run out of candidates. Note cnd = 0
                else
                {
                    T[pos] = 0;
                    pos++;
                }
            }
        }