sunday算法据说是效率比KMP,BM都好的算法
sunday算法的关注点与kmp算法不一样,sunday算法关注的是目标串
匹配则好,如果不匹配,则看下一位是否在模式串中(因为当前已经失配,那么下一位肯定是要参与匹配的)
如果下一位在模式串中有,则关于最右边的这位进行对齐(因为可能这个下一位在模式串中不止一个)
下面模拟一下算法
第一趟
a | c | a | b | a | a | b | a | a | b | c | a | c | a | a | b | c |
a | b | a | a | b | c | a | c |
第二趟
a | c | a | b | a | a | b | a | a | b | c | a | c | a | a | b | c |
a | b | a | a | b | c | a | c |
失配,看i的下一位是c,在模式串中有好几个,将最右边的一个与它对齐
第三趟
a | c | a | b | a | a | b | a | a | b | c | a | c | a | a | b | c |
a | b | a | a | b | c | a | c |
失配,看i的下一位是a,在模式串中有好几个,将最右边的一个与它对齐
第四趟
a | c | a | b | a | a | b | a | a | b | c | a | c | a | a | b | c |
a | a | b | a | a | b | c | a | c |
匹配成功
根据上面的匹配过程,可以写出下面的Sunday算法
public int strStr(String haystack, String needle) {
int tab=0;
int i=0,j=0;
int countj=0;
int counti=0;
int k=0;
while(i<haystack.length()&&j<needle.length()) {
if(haystack.charAt(i)==needle.charAt(j)){
i++;
j++;
counti++;
countj++;
} else {
tab=i-counti+needle.length();
k=j-countj+needle.length()-1;
countj=0;
counti=0;
j=0;
while(k>=j && tab<haystack.length()&&needle.charAt(k)!=haystack.charAt(tab) ) {
k--;
}
if(k==-1) i=tab+1;
else i=tab-(k-j);
}
}
if(j==needle.length()) return tab-k;
else return -1;
}
}