zoukankan      html  css  js  c++  java
  • 扩展KMP Sunday算法

    刷题刷到kmp了  TLE了 想着还是sunday算法高效一点 还好写

    kmp和扩展kmp的思想都是在不匹配时如何高效移动原串的匹配起点
    sunday直接判断步长为模式串的长度,效率最高
    原串 s:fffsffkfsfff size n=12 匹配起点为i
    模式串 p:fsf size m=3
    每次匹配 s从i开始 p从0开始

    if 匹配成功则记录,i转到下一位置
    判断第i+m位,找该位字母在p中最后出现的位置k
    if 存在 i移到 i+m-k 位
    else i移到 i+m+1 位
    e.g.  i=0
          fffsffkfsfff        
          fsf

           ^   

    该位不匹配, i跳到 i+m = 3, s[3]=s, 在p中位置为k=1,i跳到i+m-k =2(其实就是转到长度一样的起点去判断

          fffsffkfsfff        
            fsf

               ^   

    好了匹配成功

    判断模式串每个字母最后出现位置用数组nex[ ]记录,遍历一遍p,更新就好,

    nex初始化为-1, 这样 就一起解决原串中字母在模式串中找不到时i往后移一位的问题了  (i+m -k     i+m-(-1)  模式串中存在则位置更新,否则记为-1

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<stack>
    #include<list>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> P;
    typedef pair<char,char> Pc;
    typedef long double ld;
    #define mem(x) memset(x, 0, sizeof(x))
    #define me(x) memset(x, -1, sizeof(x))
    #define fo(i,n) for(ll i=0; i<n; i++)
    #define sc(x) scanf("%lf", &x)
    #define pr(x) printf("%lld
    ", x)
    #define pri(x) printf("%lld ", x)
    #define lowbit(x) x&-x
    const ll MOD = 1e9+7;
    const ll oo = 0x3f3f3f3f;
    const ll N = 2e6 +5;
    char a[N];
    ll nex[100];
    
    void getnext(string s)
    {
        me(nex);
        ll i, n=s.size();
        for(i=0; i<n; i++)
            nex[s[i]-'a']=i;
    }
    void Sunday(string s, string p)
    {
        ll n=s.size(), m=p.size();
        getnext(p);
        for(ll i=0; i<m; i++) cout<<nex[p[i]-'a']<<" ";cout<<endl;
        ll i=0, j, k, t;
        while(i<=n-m)
        {
            j=i;
            k=0;
            while(j<n && k<m && s[j]==p[k])
                j++, k++;
            if(k==m) cout<<"match in pos"<<i<<endl;
            if(i+m<n)
                i+=(m-nex[s[i+m]-'a']);
            else {cout<<"not match"<<endl;return ;}
        }
    }
    int main()
    {
        ll i, j, k, l=0;
        ll n, m, t;
        string s, p;
        while(cin>>s>>p)
        {
            Sunday(s,p);
            cout<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    关于Velocity加减法等四则运算的迷思
    [有明信息]科目导向,精耕细作 ——浅谈房地产开发成本管理
    The Building Blocks-Enterprise Applications Part 2- Information Management and Business Analytics
    maven项目建立pom.xml报无法解析org.apache.maven.plugins:maven-resources-plugin:2.4.3
    编程离不开生活
    原声JS瀑布流加延迟载入
    uva 11722
    Android自定义控件View(三)组合控件
    Android自定义控件View(二)继承控件
    Android自定义控件View(一)
  • 原文地址:https://www.cnblogs.com/op-z/p/10896135.html
Copyright © 2011-2022 走看看