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;
}
};