字符串匹配sunday算法

来源:互联网 发布:描写恋人相遇的数据 编辑:程序博客网 时间:2024/05/20 18:45

在网上看到了一种比KMP和BM算法还快字符串匹配算法,就看了一下,并且发现一些博客上写的代码是错误的,于是我也写了一个,LeetCode上测试通过。

首先对Sunday算法进行一下讲解(从别的地方复制过来的,讲的确实不错)


好了,sunday算法还真的很好理解,用下面的例子来说明吧:
  j                                k
t h i s  i s  a  s i m p l e  e x a m p l e . e x a m p l e                     i      
这个例子中上面的字符串是待查找字符串,下面的是子串。sunday的思想是这样的:

首先i,j两个指针指示的位置(也就是从头开始匹配),当发现失配的时候就判断子串的后一位在母串的字符(在上面的例子中是空格字符,k标记处)是否在子串中存在?如果存在则将该位置和子串中的该字符对齐,在从头开始匹配。如果不存在就将子串向后移动,和母串k+1处的字符对齐,再进行匹配。重复上面的操作直到找到,或母串被找完结束。

对于上面的例子继续进行,刚才说了失配,并且空格在子串中不存在,所以子串向后移动,子串的第一个字符和母串的k+1位置的字符对齐,如下图:

                                 j                                 k
t h i s  i s  a  s i m p l e  e x a m p l e .         e x a mp l e           
                                 i

这次比较还是失配,但是k位置的e在子串中出现了,而且第一个就是,最后一个也是,这时候一定要将子串中靠后出现的e和母串中的e对齐如下图:
                                       j                               k
t h i s  i s  a  s i m p l e  e x a m p l e .          e x am p l e                                                i

为什么是最靠后的一个呢?如果这里用第一个e来和母串中的e对齐,就有可能将中间出现的可匹配字符串空过去。

同上这次还是失配,所以还要再进行一次。

t h i s  i s  a  s i m p l e  e x a m p l e .            
     ex amp l e  
这次就匹配成功了。

下面这段代码也是我根据别人的稍加更改,LeetCode28亲测通过:
int Solution::strStr(string haystack, string needle)
{
if(needle.length()==0)
return 0;


int h_len=haystack.length();
int n_len=needle.length();


int hi=0,ni=0,pos;
while(hi<h_len)
{
ni=0;
while(ni<n_len&&haystack[hi+ni]==needle[ni])
{
ni++;
continue;
}
if(ni==n_len)
return hi;
pos=findLetter(needle,haystack[hi+n_len]);
if(pos!=-1)//包含
{
hi=hi+n_len-pos;
}
else//不包含
{
hi=hi+n_len+1;
}
}
return -1;
    }
int Solution::findLetter(string needle,char p)
{
int pos=-1;
for(int i=needle.length()-1;i>=0;i--)
{
if(needle[i]==p)
{
pos=i;
break;
}
}
return pos;
}

1 0
原创粉丝点击