1. 程式人生 > >【KMP】字符串匹配

【KMP】字符串匹配

esp 一次 AD 難點 main 問題: clu space names

問題:

字符串s="ABBCABCDABDADSBC",p="ABCDABD",問p在s中第一次出現的索引,未找到則返回-1

思路:

暴力求解:時間復雜度O(m*n),其中m、n分別為s、p的長度

KMP算法:時間復雜度O(m+n)

利用next[],存儲字符串p中的前後綴相同的長度。

即next[j]=p[0~j-1]中前綴和後綴相同的長度,next[0]=-1,難點在於求next數組

 1 #include <iostream>
 2 #include <string>
 3 #include <string.h>
 4 #include <map>
 5
#include <set> 6 #include <list> 7 #include <vector> 8 #include <deque> 9 #include <unordered_set> 10 #include <algorithm> 11 #include <unordered_map> 12 #include <stack> 13 #include <cstdio> 14 #include <memory> 15 using namespace std;
16 17 int* getNext(string &s) 18 { 19 int *next = new int[s.size()]; 20 next[0] = -1; 21 int k = -1, j = 0; 22 while (j < s.size() - 1) 23 { 24 if (k == -1 || s[j] == s[k]) 25 { 26 j++; 27 k++; 28 next[j] = k; 29 }
30 else 31 { 32 k = next[k]; 33 } 34 } 35 return next; 36 } 37 38 int kmp(string &s, string &p,int next[]) 39 { 40 int i = 0, j = 0; 41 while (i < s.size() && j < p.length()) 42 { 43 if (j == -1 || s[i] == p[j]) 44 { 45 i++;j++; 46 } 47 else 48 { 49 j = next[j]; //j跳到相同前綴的後面 50 } 51 } 52 if (j == p.size()) 53 return i-j; 54 else 55 return -1; 56 } 57 58 int main() 59 { 60 string s = "ABBCABCDABDADSBC", p = "ABCDABD"; 61 cout << kmp(s, p, getNext(p))<<endl; 62 int *a = getNext(p); 63 for (int i = 0;i < 7;i++) 64 cout << a[i] << ; 65 cout << endl; 66 return 0; 67 }

【KMP】字符串匹配