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;
    }
    

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

  • 相关阅读:
    cache buffers chains latch
    freemarker自定义标签报错(七)
    freemarker自定义标签(三)-nested指令
    freemarker自定义标签(二)
    Buffer Cache 原理
    JavaScript去除日期中的“-”
    JavaScript替换HTML标签
    JavaScript获取地址栏中的参数
    JavaScript中的indexOf
    Java中的字符串拼接
  • 原文地址:https://www.cnblogs.com/hqwhqwhq/p/4811904.html
Copyright © 2011-2022 走看看