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]分別計算的是
a,ab,aba,abab,ababa,ababac,ababaca的相同的最長前綴和最長後綴的長度。因爲a,ab,aba,abab,ababa,ababac,ababaca的相同的最長前綴和最長後綴是「」,「」,「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