Leetcode 28 实现strStr
题目描述
题解1(find)
class Solution {
public:
int strStr(string haystack, string needle) {
return haystack.find(needle);
}
};
题解2(KMP)
class Solution {
private:
vector<int> nextj;
void getnext(string s){
nextj.resize(s.size());
int j=-1;
nextj[0]=j;
for(int i = 1; i < s.size(); i++)//注意i从1开始
{
while(j >= 0 && s[i] != s[j+1])//处理前后缀不相同的情况
{
j = nextj[j];//向前回溯
}
if(s[i] == s[j+1])//找到相同的前后缀
{
j++;
}
nextj[i] = j;//将j(前缀的长度)赋给next[i]
}
}
public:
int strStr(string haystack, string needle) {
if(!needle.size()) return 0;
if(! haystack.size()) return -1;
getnext(needle);
int i = 0, j = -1;
while(i < haystack.size()){
while(j >= 0 && haystack[i]!=needle[j+1])//不匹配
{
j = nextj[j];//j寻找之前的位置
}
if(haystack[i]==needle[j+1])//匹配
{
j++;//j和i同时向后移动
}
if(j == (needle.size()-1))//文本串s里出现了模式串t
{
return (i-needle.size()+1);//返回其位置
}
i++;
}
return -1;
}
};
题解3(Sunday:参考)
class Solution {
public:
int strStr(string haystack, string needle) {
if(!needle.size()) return 0;
if(! haystack.size()) return -1;
int slen=haystack.size();
int tlen=needle.size();
int i=0,j=0;//i指向源串首位 j指向子串首位
int k;
int m=tlen;//第一次匹配时 源串中参与匹配的元素的下一位
while(i < slen)
{
if(haystack[i]!=needle[j])
{
for(k=tlen-1;k>=0;k--)//遍历查找此时子串与源串[i+tlen+1]相等的最右位置
{
if(needle[k]==haystack[m])
break;
}
i=m-k;//i为下一次匹配 源串首位(step) Sunday算法核心:最大限度跳过相同元素
j=0;//j依然为子串首位
m=i+tlen;//m为下一次参与匹配的源串最后一位元素的下一位
if(m>slen)//当下一次参与匹配的源串字数的最后一位的下一位超过源串长度时
return -1;
}
else
{
if(j==tlen-1)//若j为子串末位 匹配成功 返回源串此时匹配首位
return i-j;
i++;
j++;
}
}
return -1;//当超过源串长度时
}
};