https://leetcode.com/problems/implement-strstr/description/
思路就是 移动指向两个字符串的位置索引。如果字符匹配就往后移动,匹配下一个字符;一旦不匹配就往回移动,重新开始匹配。
简单粗暴实现方式:
class Solution { public: int strStr(string haystack, string needle) { int hsize = haystack.size(); int nsize = needle.size(); int i = 0,j = 0; while(i < hsize && j < nsize){ if(haystack[i] == needle[j]) { ++i; ++j; } else { i = i - j + 1; j = 0; } } if( j == nsize) return i-j; else return -1; } };
应用KMP算法:
先针对needle(p)字符串进行一次额外处理,得到一个对应长度的next数组(根据最长前缀后缀长度,使得无需回溯到needle字符串开头匹配)。next数组的含义,比如 next[j] = k, 代表的意思是j之前的字符串的最长前缀后缀长度为k,即p0 p1...pk-1 = pj-k...pj-2 pj-1。
class Solution { public: int strStr(string haystack, string needle) { if(needle.size() <= 0) return 0; vector<int> next = buildNext(needle); if(next.size() > 0) { int i = 0; int j = 0; while(i < haystack.size()) { if(j == -1 || haystack[i] == needle[j]) { ++i; ++j; } else { j = next[j]; } if(j == needle.size()) { return i - j; } } } return -1; } private: vector<int> buildNext(string needle) { if(needle.size() <= 0) return vector<int>(); vector<int> next(needle.size(), -1); int j = 0; int k = -1; while(j < needle.size() - 1) { if(k == -1 || needle[k] == needle[j]) { ++j; ++k; next[j] = k; } else { k = next[k]; } } return next; } };