Sunday算法

Posted ck666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sunday算法相关的知识,希望对你有一定的参考价值。

Sunday算法

2017-08-30


Sunday算法是Daniel M.Sunday于1990年提出的字符串模式匹配。并不知道他是谁(来自百度)


Q:那么Sunday是干什么的?

s:吾看他能在期望O(n)的时间里知道在串S1中S2出现了几次x

Q:那他是怎么实现的呢?

s:就是在字符串发生失配的时候,跳过了尽可能多的字符,而且保证不错过某些可能的情况poi

s:那我举一个例子

S1串是   wypxs_a_b_e_rfliflisabersakeLLpoix

S2串是   saber

现在上面用i表示匹配到S1的第i个字符,j表示匹配到S2的第j个字符

显然在S1中只有一个S2。

那么Sunday怎么匹配的?   

wypxs_a_b_e_rfliflisaberlikeLLpoix

w y p x s _ a _ b _ e _ r f l i f l i s a b e r s a k e L L p o i x
s a b e r                                                          

这是一开始的样子,发现第一个不一样。按照Sunday,就去S1的下一位找S2的字符.

S1中的下一个是‘_‘发现在S2中没有,就移动len(S2)+1;变成

w y p x s _ a _ b _ e _ r f l i f l i s a b e r s a k e L L p o i x
            s a b e                                            

这样还是刚才的操作,发现第一个还是不匹配,依旧移动len(S2)+1

w y p x s _ a _ b _ e _ r f l i f l i s a b e r s a k e L L p o i x
                        s a b e                                  

然后.....这个有点长啊.......

w y p x s _ a _ b _ e _ r f l i f l i s a b e r s a k e L L p o i x
                                    s a b e r                      

现在还是不匹配?关键来了!发现不匹配了。现在看到了S1下一位是r,在S2中也有r,那这样吧r对其

w y p x s _ a _ b _ e _ r f l i f l i s a b e r s a k e L L p o i x
                                      s a b e r                    

现在竟然匹配了!然后ans++;可以继续跳了,找到下一个s,对齐

w y p x s _ a _ b _ e _ r f l i f l i s a b e r s a k e L L p o i x
                                                s a b e r          

到‘k’不匹配没有,看到下一位L跳6个,发现没了。结束ans最后的

这样就可以保证跳到的都是可能会合法的情况,而且距离尽可能大.....poi

每一次贪心选最后一个字符出现的位置即如果S2是’ssaber‘碰到‘s’只跳到第二个‘s’的位置而不是第一个poi

技术分享
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define next saber
using namespace std;
char a[10000000+99999],b[5000+99];
int len1,len2,ans;
int next[30];
bool pd(int i){
    for(int j=0;j<len2;j++)
     if(a[i+j]!=b[j]){return 1;}
     return 0;
}
int main(){
    cin>>a;cin>>b;
    len1=strlen(a),len2=strlen(b);
    for(int i=0;i<=26;i++)next[i]=len2+1;
    for(int i=0;i<len2;i++)next[b[i]-a]=len2-i;
    for(int i=len1;i<=len1+99;i++)a[i]=z+1;
    next[z+1-a]=len2+1;
    int i=0;
    while(i<len1){
        if(pd(i))i+=next[a[i+len2]-a];
        else ans++,cout<<i+1<<" ",i+=next[a[i+len2]-a];
    }
    cout<<endl;
    cout<<ans;
    return 0;
} 
Sunday

by:s_a_b_e_r


 

以上是关于Sunday算法的主要内容,如果未能解决你的问题,请参考以下文章

字符串匹配的sunday算法

Sunday算法

Sunday算法

Sunday算法模板

字符串模式匹配算法 Sunday算法

字符串的模式匹配:Sunday 算法