LeetCode: Implement strStr()(字符串匹配:Sunday算法)
Implement strStr().
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
暴利解法:一个一个反复比较。没有尝试。
函数调用:find()。
Sunday算法:由于KMP没有尝试过,就写了个较容易的算法,这些算法重点在于如何能够跳的更远,躲避多数比较。
Reference:百度百科
http://baike.baidu.com/link?url=WL3rbdPYVgtN_kw63fKSSUcd4uezE1K5J_5FejGvGH5MQmAUaiwVw1iiCBwG3Ikq2v7CPTnEJkVUPDcCZMdEja
class Solution {
public:
//寻找在模式串右边首次出现索引
int exist(const string &s,const char &c)
{
int len=s.length();
for(int i=len;i>=0;--i)
{
if(s[i]==c)
{
return i;
}
}
return -1;
}
int strStr(string haystack, string needle) {
/*Sunday算法:当出现不匹配的时候,
*却不是去找匹配串中不匹配的字符在模式串的位置,
*而是直接找最右边对齐的右一位的那个字符在模式串的位置。
*/
if(needle.empty()) return 0;
if(haystack.empty()) return -1;
auto iterh=haystack.cbegin(),itern=needle.cbegin();
int len=needle.length();
for(;iterh!=haystack.cend()&&itern!=needle.cend();)
{
auto iterh1=iterh,itern1=itern;
//匹配
for(;iterh1!=haystack.cend()&&itern1!=needle.cend()&&*iterh1==*itern1;++iterh1,++itern1);
if(itern1!=needle.cend())//fail
{
iterh1=iterh+len;//最右边对齐的右一位
if(iterh1<haystack.cend())
{
int i=exist(needle,*iterh1);//check
if(i==-1)
{
iterh+=(len+1);//不存在,右移模式串长度+1
}
else
{
/*存在,则后对齐,重新匹配,
*从后面check原因:
*防止出现两个相同字符,导致中间跳跃
*ABCD(匹配)看下一个D,就知道了
*DCD(模式)
*/
iterh+=(len-i);
}
}
else
{
return -1;
}
}
else
{
return iterh1-haystack.cbegin()-len;//iterh1是合格的下一个字符串,所以不用+1
}
}
return -1;
// return haystack.find(needle);//API解法,耗时竟然一样,我都惊讶了
}
};