zoukankan      html  css  js  c++  java
  • 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_rfliflisabersakeLLpoix

    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


  • 相关阅读:
    第九次作业
    第八次作业
    第七次作业
    组合数学—递推关系与母函数
    组合数学—排列组合
    三角函数
    OpenCV初步
    计算机视觉如何入门
    GDB调试技巧:总结篇
    PyQt5之窗口类型
  • 原文地址:https://www.cnblogs.com/ck666/p/7455195.html
Copyright © 2011-2022 走看看