[LeetCode] 28. Implement strStr()
本题要实现strstr()函数,可以用两种字符串的模式匹配算法来实现:
第一种算法(简单模式匹配算法):
1 class Solution 2 { 3 public: 4 int NaiveStrMatching(string T, string P) 5 { 6 int i = 0, j = 0; 7 int plen = P.length(); 8 int tlen = T.length(); 9 if(tlen < plen) return -1; 10 while(i < tlen && j < plen) 11 { 12 if(T[i] == P[j]) 13 { 14 i ++; 15 j ++; 16 } 17 else 18 { 19 i = i - j + 1; //下一趟比较 20 j = 0; 21 } 22 } 23 if(j >= plen) return i - j; //匹配成功 24 else return -1; 25 } 26 int strStr(string haystack, string needle) 27 { 28 return NaiveStrMatching(haystack,needle); 29 } 30 };
第二种算法(KMP算法):
1 class Solution 2 { 3 public: 4 int *Next(string P) 5 { 6 int m = P.length(); //模式P的长度 7 int * N = new int[m]; 8 N[0] = 0; 9 for(int i = 1; i < m; i ++) //对P的每一个位置进行分析 10 { 11 int k = N[i-1]; //第i-1位置的最长前缀串长度 12 while(k > 0 && P[i] != P[k]) 13 k = N[k - 1]; 14 if(P[i] == P[k]) 15 N[i] = k + 1; 16 else 17 N[i] = 0; 18 } 19 return N; 20 } 21 22 int KMPStrMatching(string T,string P,int *N,int startIndex) 23 { 24 if(P == "") 25 return 0; 26 int lastIndex = T.length() - P.length(); 27 if(lastIndex < startIndex) return -1; 28 int i; //指向T内部字符的游标 29 int j = 0; //指向P内部字符的游标 30 for(i = startIndex; i < T.length(); i ++) 31 { 32 while(P[j] != T[i] && j > 0) 33 j = N[j - 1]; 34 if(P[j] == T[i]) //当P的第j位和T的第i位相同时,则继续 35 j ++; 36 if(j == P.length()) 37 return i - j + 1; //匹配成功,返回该T子串的开始位置 38 } 39 return -1; 40 } 41 42 int strStr(string haystack, string needle) 43 { 44 int *n = Next(needle); 45 return KMPStrMatching(haystack,needle,n,0); 46 } 47 };
由上可知KMP算法的效率比BF算法要高得多。