KMP算法
KMP算法:
算法源自:
https://www.bilibili.com/video/BV1Px411z7Yo?share_source=copy_web
https://www.bilibili.com/video/BV1hW411a7ys?share_source=copy_web
1 #include <string> 2 #include <vector> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 7 class Solution 8 { 9 public: 10 // 生成前缀表 11 void GeneratePerfixTable(string pattern, vector<int> &prefixTable) { 12 prefixTable[0] = 0; 13 int len = 0; // 相等前后缀最大长度 14 int i = 1; 15 int n = pattern.size(); 16 while (i < n) { 17 // 如果当前位置字符与相等前后缀最大长度位置字符相同,则相等前后缀最大长度增加 18 // 填写当前匹配位置对应前缀表中的值为len,让i++继续匹配下个字符 19 if (pattern[i] == pattern[len]) { 20 len++; 21 prefixTable[i] = len; 22 i++; 23 } else { 24 // 匹配失败时 25 if (len > 0) { 26 len = prefixTable[len - 1]; 27 } else { 28 prefixTable[i] = len; 29 i++; 30 } 31 } 32 } 33 } 34 // 第一个前缀表值转换为-1 35 void ShiftPrefixTable(vector<int> &prefixTable) { 36 int n = prefixTable.size(); 37 for (int i = n - 1; i > 0; i--) { 38 prefixTable[i] = prefixTable[i - 1]; 39 } 40 prefixTable[0] = -1; 41 } 42 // 打印前缀表 43 void PrintPrefixTable(const vector<int> &prefixTable) { 44 for (const auto &val : prefixTable) { 45 cout << val << " "; 46 } 47 cout << endl; 48 } 49 int Kmp(string text, string pattern) { 50 int m = text.size(); 51 int n = pattern.size(); 52 if ((m == 0) || (n == 0) || m < n) { 53 return -1; 54 } 55 vector<int> prefixTable(n); 56 GeneratePerfixTable(pattern, prefixTable); 57 ShiftPrefixTable(prefixTable); 58 PrintPrefixTable(prefixTable); 59 60 int i = 0; 61 int j = 0; 62 while (i < m) { 63 // 如果模式串匹配到最后一个字符且与文本串中字符相同,则找到文本串中存在相同的模式串 64 if ((j == n - 1) && text[i] == pattern[j]) { 65 return i - j; 66 // j = pattern[j]; // 如果需要找出所有匹配的模式串位置 67 } 68 if (text[i] == pattern[j]) { 69 i++; 70 j++; 71 } else { 72 // 匹配不到,则回溯到上次已匹配成功的位置 73 j = prefixTable[j]; 74 if (j == -1) { 75 i++; 76 j++; 77 } 78 } 79 } 80 return -1; 81 } 82 }; 83 84 int main() 85 { 86 Solution *test = new Solution(); 87 string text = "ABABABCABAABABABABA"; 88 string pattern = "ABABCABAA"; 89 // KMP算法找到文本串中包含模式串的首次位置 90 cout << test->Kmp(text, pattern) << endl; // 1 91 system("pause"); 92 return 0; 93 }
运行效果:

浙公网安备 33010602011771号