KMP算法


參考《大話數據結構》 P135

 

KMP算法用於字符串匹配,kmp算法完成的任務是:給定兩個字符串O和f,長度分別為n和m,判斷f是否在O中出現,如果出現則返回出現的位置。常規方法是遍歷a的每一個位置,然后從該位置開始和b進行匹配,但是這種方法的復雜度是O(nm)。kmp算法通過一個O(m)的預處理,使匹配的復雜度降為O(n+m)

思想:

朴素匹配算法需要兩個指針i,j都遍歷一遍字符串,故復雜度m*n

KMP算法i指針不回溯,j指針的回溯參考next數組,體現了動態規划的思想

原理如下:

藍色表示匹配,紅色為失配

分析藍色部分

如果存在最長公共前后綴的話,比如這樣:

就可以在下次匹配的時候用,這樣避免了i的回溯

實現:

next數組的意義:當模式匹配串T失效的時候,next數組對應的元素知道應該使用T串的哪個元素進行下一輪匹配

 1 #include <string>
 2 
 3 void get_next(string T, int *next)
 4 {
 5     int i = 1;    //后綴
 6     int j = 0;    //前綴
 7     next[1] = 0;
 8     while (i < T[0])    //T[0]表示字符串長度
 9     {
10         if (j == 0 || T[i] == T[j])
11         {
12             i++;
13             j++;
14             next[i] = j;
15         }
16         else
17             j = next[j];
18     }
19 }
20 
21 int KMP(string S, string T, int pos)
22 {
23     int i = pos;    //標記主串S下標
24     int j = 1;        //匹配串下標
25     int next[255];
26     get_next(T, next);
27     while (i <= S[0] && j <= T[0])    //0位置都放字符串長度
28     {
29         if (j == 0 || S[i] == T[j])
30         {
31             i++;
32             j++;
33         }
34         else
35             j = next[j];    //j退回到合適位置,i不用再回溯了
36         if (j > T[0])    //如果存在j在匹配完最后一個元素后又++了,所以會大於長度
37             return i - T[0];    //i的位置減去匹配串的長度就是匹配串出現的位置
38         else
39             return 0;
40     }
41 }

 

改進

會出現一種特殊情況:

S = “aaaabcde”

T = "aaaaax"

這樣的話next數組為012345,實際上由於前面都是a,直接調到第一個a就可以了,期望的next數組為000005

這樣next數組構造改為12-15行

 1 void get_next(string T, int *next)
 2 {
 3     int i = 1;    //后綴
 4     int j = 0;    //前綴
 5     next[1] = 0;
 6     while (i < T[0])    //T[0]表示字符串長度
 7     {
 8         if (j == 0 || T[i] == T[j])
 9         {
10             i++;
11             j++;
12             if (T[i] != T[j])
13                 next[i] = j;
14             else
15                 next[i] = next[j];
16         }
17         else
18             j = next[j];
19     }
20 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM