zoukankan      html  css  js  c++  java
  • 字符串处理——Tire树__LA3942

    其实Trie树并没有听上去那么高级。首先它是把所有的单词存到了一棵树里面,说白了,就是按照一个单词的前缀来存。不过这棵树不需要按照严格意义上的树来了,实际上,只需要用ch[u][i]来存就好了,而ch[u][i]代表的就是整棵树,ch[u][i]的值为树的节点值,即时遍历的时间戳。u代表的是当前节点值,ch[u][i]代表的是u的儿子节点中单词'i'代表的节点值,如果ch[u][i] = 0,那么我们可以认为这个节点不存在,如果不等于0那么我们认为存在。每一个节点除了节点值(时间戳)外,还有一个权值,我们不妨中间节点的权值附成0,单词最后的那个字母对应的节点的权值附成-1,代表这个位置是一个单词。sz代表的就是当前共有的节点总数。insert函数就是插入单词,这个也比较好写。
    大白皮上面把Trie树写在了结构体里面,这样好像直接就限制了ch[][]的范围,应该不是以堆的形式来存了。其实完全不需要,看了上面的解释就知道了,不过感觉还是直接定义一个Trie结构体比较好看一点。。。(然而并没有什么卵用)。就用大白皮上面的那道LA_3942为例吧。下面是代码。
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #define FOR(i,x,y)  for(int i = x;i < y;i ++)
    #define IFOR(i,x,y) for(int i = x;i > y;i --)
    #define MOD  20071027
    
    using namespace std;
    
    int ch[4005*105][26],sz,val[4005*105],len[300005],cnt;
    int dp[300005];
    char s[300005];
    
    void init(){
        memset(ch[0],0,sizeof(ch[0]));
        sz = 1;
    }
    
    void insert(char* str,int v){
        int n = strlen(str),u = 0;
        FOR(i,0,n){
            int c = str[i] - 'a';
            if(!ch[u][c]){
                memset(ch[sz],0,sizeof(ch[sz]));
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u] = v;
    }
    
    void find(char* str){
        cnt = 0;
        int n = strlen(str),u = 0;
        FOR(i,0,n){
            int c = str[i] - 'a';
            if(!ch[u][c])   return;
            int id = ch[u][c];
            if(val[id]) len[cnt++] = (i+1);
            u = id;
        }
        return ;
    }
    
    int main(){
        //freopen("test.in","r",stdin);
        int tCase = 0;
        while(~scanf("%s",s)){
            printf("Case %d: ",++tCase);
            init();
            int n;
            char str[105];
            scanf("%d",&n);
            while(n--){
                scanf("%s",str);
                insert(str,-1);
            }
            n = strlen(s);
            dp[n] = 1;
            IFOR(i,n-1,-1){
                find(s+i);
                dp[i] = 0;
                FOR(j,0,cnt){
                    dp[i] += dp[i+len[j]];
                    dp[i] %= MOD;
                }
            }
            printf("%d
    ",dp[0]);
        }
        return 0;
    }
    

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    array and ram
    char as int
    pointer of 2d array and address
    Install SAP HANA EXPRESS on Google Cloud Platform
    Ubuntu remount hard drive
    Compile OpenSSL with Visual Studio 2019
    Install Jupyter notebook and tensorflow on Ubuntu 18.04
    Build OpenCV text(OCR) module on windows with Visual Studio 2019
    Reinstall VirtualBox 6.0 on Ubuntu 18.04
    Pitfall in std::vector<cv::Mat>
  • 原文地址:https://www.cnblogs.com/hqwhqwhq/p/4811904.html
Copyright © 2011-2022 走看看