• 字符串专题:后缀数组


     后缀数组模板,复杂度:O(Nlog2n),用时要注意时间,这个比较耗时间

    /*
    后缀数组模板
    asdfghjkl
    ghj
    对两个串匹配 有ghj返回1 必须连续
    */
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int n,k;
    int rank[100005],tmp[100005],sa[100005];
    bool common_sa(int i,int j)
    {
        if(rank[i]!=rank[j]) return rank[i]<rank[j];
        else
        {
            int ri=i+k<=n?rank[i+k]:-1;
            int rj=j+k<=n?rank[i+k]:-1;
            return ri<rj;
        }
    }
    void construct_sa(string s,int *sa)
    {
        n=s.length();
        for(int i=0;i<=n;i++)
        {
            sa[i]=i;
            rank[i]=i<n?s[i]:-1;
        }
        for(k=1;k<=n;k*=2)
        {
            sort(sa,sa+n+1,common_sa);
            tmp[sa[0]]=0;
            for(int i=1;i<=n;i++)
            {
                tmp[sa[i]]=tmp[sa[i-1]]+(common_sa(sa[i-1],sa[i])?1:0);
            }
            for(int i=0;i<=n;i++)
            {
                rank[i]=tmp[i];
            }
        }
    }
    bool contain(string s,int *sa,string t)
    {
        int a=0,b=s.length();
        while(b-a>1)
        {
            int c=(a+b)/2;
            if(s.compare(sa[c],t.length(),t)<0) a=c;
            else b=c;
        }
        return s.compare(sa[b],t.length(),t)==0;
    }
    
    int main()
    {
        string mode,donser;
        while(cin>>donser>>mode)
        {
            n=donser.size();
            construct_sa(donser,sa);
            if(contain(donser,sa,mode)) cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
        return 0;
    }
  • 相关阅读:
    线程执行器(一)
    修改锁的公平性
    Spark学习视频整合
    使用读写锁实现同步数据访问
    使用锁实现同步
    使用工厂类创建线程
    线程的分组
    android手机状态解释,比方android.os.Build.VERSION.SDK
    Android-Dalvik指令集
    selenium使用Xpath定位之完整篇
  • 原文地址:https://www.cnblogs.com/dzzy/p/5475637.html
Copyright © 2020-2023  润新知