• 字符串模板


    kmp

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    const ll N = 1e6 + 9;
    const ll inf = 0x3f3f3f3f;
    char a[N];
    char b[N];
    int ne[N];
    void solve() {
        scanf("%s", (a + 1));
        scanf("%s", (b + 1));
        int n = strlen(b + 1);
        int m = strlen(a + 1);
        for (int i = 2, j = 0; i <= n; i ++) {
            while (j && b[i] != b[j + 1])j = ne[j];
            ne[i] = (b[j + 1] == b[i]?++j:j);
        }
        for (int i = 1, j = 0; i <= m; i ++) {
            while ( j && b[j + 1] != a[i])j = ne[j];
            if (b[j + 1] == a[i])j++;
            if (j == n) {
                printf("%d
    ", i-n + 1  );
            }
        }
        for (int i = 1; i <= n; i ++) printf("%d ", ne[i]);
    }
    signed main() {
       ll t = 1;//cin >> t;
       while (t--) solve();
    }
    

    ac自动机

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    const ll N = 1e5 + 9;
    const ll inf = 0x3f3f3f3f;
    int n;
    vector<int>G[N];
    string ch[N];
    queue<int>q;
    int dp[N];
    struct AC {
        int tr[N][27],  idx;
        string str;
        int ne[N];
    
        void init() {
            memset(tr, 0, sizeof tr);
            memset(ne, 0, sizeof ne);
            memset(dp, 0, sizeof dp);
            memset(ch, 0, sizeof ch);
            for (int i = 0; i <= n; i ++) {
                G[i].clear();
            }
            idx = 0;
        }
        void insert() {
            int p = 0;
            for (int i = 0; str[i]; i ++) {
                int t = str[i] - 'a';
                if (!tr[p][t])tr[p][t] = ++ idx;
                p = tr[p][t];
            }
            ch[p] = str;
        }
        void build() {
            while (!q.empty())q.pop();
            for (int i = 0; i < 26; i ++) 
                if (tr[0][i])q.push(tr[0][i]);
            while (!q.empty()) {
                int u = q.front();
                q.pop();
                for (int i = 0; i < 26; i ++) {
                    int p = tr[u][i];
                    if (p) {//这里是手画理解的
                        ne[p] = tr[ne[u]][i];
                        q.push(p);
                    } else 
                        tr[u][i] = tr[ne[u]][i];
                } 
            }
        }
    }T;
    vector<string> ans;
    int ans_cnt;
    
    void solve() {
    while (~scanf("%d", &n)) {
        if (n == 0)exit(0);
        ans_cnt = 0;
        T.init();
        for (int i = 0; i < n; i ++) {
            cin >> T.str;
            T.insert();
        }
        T.build();
        for (int i = 1; i <= T.idx; i ++) {
            G[i].push_back(T.ne[i]);
            G[T.ne[i]].push_back(i);
        }
        cin >> T.str;
        int res = 0;
        for (int i = 0, j = 0; T.str[i]; i ++) {
            int t = T.str[i] - 'a';
            while (j && !T.tr[j][t])j = T.ne[j];
            if (T.tr[j][t]) j = T.tr[j][t];
            int p = j;
            while (p ) {//这里就正常找
                dp[p]++;
                p = T.ne[p];
            }
        }
        for (int i = 0; i <= T.idx; i ++) {
            if (ch[i].size() != 0) {
                if (dp[i] > ans_cnt) {
                    ans_cnt = dp[i];ans.clear();
                    ans.push_back(ch[i]);
                } else if (dp[i] == ans_cnt){
                    ans.push_back(ch[i]);
                }
            }
        }
        cout << ans_cnt <<"
    ";
        for (auto s:ans)cout << s << "
    ";
    }
    }
    signed main() {
       ll t = 1;//cin >> t;
        //scanf("%d", &t);
       while (t--) {
          solve();
       }
    }
    

    后缀数组

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    const ll N = 1e6 + 9;
    const ll inf = 0x3f3f3f3f;
    struct Suffix_Array{
        int n,m,x[N],y[N],H[N],SA[N],cnt[N],rank[N],Height[N];char s[N];
        //Suf[i]: s[i,n]
        //len: 已经求出了长度为len的串的排名
        //x[i]: Suf[i]的排名 (排序第一关键字) (上一次排序后得到的rank[i])
        //y[i]: 按第len个字符排出来的顺序(排序第二关键字) (第二关键字排名为i的数的位置)
        //H[i]: H[i]=Height[rank[i]] 即 LCP(Suf[i],Suf[SA[rank[i]-1]])
        //SA[i]: 排名为i的后缀第一个字符所在位置
        //cnt[i]: 第一关键字排名为 i(1~i)的数有多少个
        //rank[i]: Suf[i]的排名
        //Height[i]: Height[i]=H[SA[i]] 即 LCP(Suf[SA[i]],Suf[SA[i-1]])
        inline void get_SA(){
            m=128;
            memset(cnt, 0, sizeof cnt);
            memset(rank, 0, sizeof rank);
            for(int i=1;i<=n;++i)++cnt[x[i]=s[i]];
            for(int i=2;i<=m;++i)cnt[i]+=cnt[i-1];
            for(int i=n;i>=1;--i)SA[cnt[x[i]]--]=i;
            for(int len=1;len<=n;len<<=1){
                int t=0;
                for(int i=n-len+1;i<=n;++i)y[++t]=i;
                for(int i=1;i<=n;++i)if(SA[i]>len)y[++t]=SA[i]-len;
                for(int i=1;i<=m;++i)cnt[i]=0;
                for(int i=1;i<=n;++i)++cnt[x[i]];
                for(int i=2;i<=m;++i)cnt[i]+=cnt[i-1];
                for(int i=n;i>=1;--i)SA[cnt[x[y[i]]]--]=y[i],y[i]=0;
                swap(x,y);
                x[SA[1]]=m=1;//把旧的x存进了y并清零x
                for(int i=2;i<=n;++i)
                    x[SA[i]]=(y[SA[i]]==y[SA[i-1]]&&y[SA[i]+len]==y[SA[i-1]+len])?m:++m;//注意这里的SA[i]+len和SA[i-1]+len有可能访问到n+1,所以上面的N最好稍开大一点,不要尝试卡这点小常数空间
                if(m==n)break;
            }
            
        }
        inline void get_Height(){
            for(int i=1;i<=n;++i)rank[SA[i]]=i;
            for(int i=1,k=0;i<=n;++i){
                if(rank[i]==1)continue;
                if(k)--k;//H[i-1]-1<=H[i]
                int j=SA[rank[i]-1];
                while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k])++k;
                Height[rank[i]]=k;
            }
    //        for(int i=1;i<=n;++i)printf("%d ",Height[i]);
        }
    }SA;
    void solve() {
        cin >> (SA.s + 1);
        SA.n = strlen(SA.s + 1);
        SA.get_SA();
        SA.get_Height();
        
    }
    signed main() {
       ll t = 1;//cin >> t;
       while (t--) {
          solve();
       }
    }
    
  • 相关阅读:
    Ibatis 使用心得
    java.net.ConnectException: Connection timed out
    ZK 最少限度加载页面js文件
    JAVA 获取网页流
    ZK 页面间参数传递
    删除 TOMCAT 上次关闭遗留下来的 SESSION 缓存
    Java 异常java.lang.IllegalArgumentException: Illegal group reference
    ZK textbox Constraint验证
    zk textbox 更改字体大小及高度
    通过http管理solrcore
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/15165532.html
Copyright © 2020-2023  润新知