KMP算法

Kmp算法和BF算法的區別在於不須要把「搜索位置」移動到已經比較過的位置。html

 例子-->算法

  ->移動位數 = 已經匹配的字符數 - 對應匹配部分字符串前綴和後綴共有長度c#

如以上主串中的「abab」和目標串中的「abad」,已經匹配的字符數爲3(「aba」),數組

「aba」的前綴爲[a,ab],後綴爲[ba,a]。共有「a」的長度爲1 ,移動位數=3-1=2;spa

所以目標串中的匹配字符串前綴和後綴信息是固定的,我如今只須要把這個信息放在一個數組裏.net

   ->next數組的含義就是一個固定字符串的最長前綴和最長後綴相同的長度。code

對於目標字符串ptr,ababaca,長度是7,因此next[0],next[1],next[2],next[3],next[4],next[5],next[6]分別計算的是 
aababaababababaababacababaca的相同的最長前綴和最長後綴的長度。因爲aababaababababaababacababaca的相同的最長前綴和最長後綴是「」,「」,「a」,「ab」,「aba」,「」,「a」,因此next數組的值是[-1,-1,0,1,2,-1,0],這裏-1表示不存在,0表示存在長度爲1,2表示存在長度爲3。htm

求next數組c#代碼-->blog

        private static unsafe int[] cal_next(string str)
        {
            int len = str.Length;
            int[] next = new int[len];
            next[0] = -1;
            int k = -1;
            for (int q=1;q< len;q++)
            {
                while(k>-1&&str[k+1]!=str[q])
                {
                    k = next[k];
                }
                if (str[k+1] == str[q])
                {
                    k = k + 1;
                }
                next[q] = k;
            }
            return next;

        }

求匹配位置kmr c#代碼-->字符串

        private static int kmr(string m,string s)
        {
            int m_len = m.Length;
            int s_len = s.Length;
            int[] next = cal_next(s);
            int k = -1;
            for(int i=0;i<m_len;i++)
            {
                while(k>-1 && s[k+1]!=m[i])
                {
                    k = next[k];
                }
                if (s[k+1] == m[i])
                {
                    k = k + 1;
                }
                if(k==s_len-1)
                {
                    return i - s_len + 1;
                }
            }
            return -1;
        }

  參考-->

1-> http://blog.csdn.net/hyjoker/article/details/51190726

2-> https://www.cnblogs.com/huangxincheng/archive/2012/12/01/2796993.html

相關文章
相關標籤/搜索