模板 : 

#include<string.h>
#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<algorithm>
using namespace std;
;

struct Trie
{
    Trie *Next[maxn];
    int v;
    inline void init(){
        ;
        ; i<maxn; i++)
            this->Next[i] = NULL;
    }
};
Trie *root = (Trie *)malloc(sizeof(Trie));

void CreateTrie(char *str)
{
    int len = strlen(str);
    Trie *p = root, *tmp;
    ; i<len; i++){
        int idx = str[i]-'a';

        if(p->Next[idx] == NULL){
            tmp = (Trie *)malloc(sizeof(Trie));
            tmp->init();
            p->Next[idx] = tmp;
        }else p->Next[idx]->v++;

        p = p->Next[idx];
    }
    p->v = -;//若为结尾,则将v改成-1,当然字典树里面的变量都是要依据题目
              //设置并且在特定位置赋值的
}

int FindTrie(char *str)
{
    int len = strlen(str);
    Trie *p = root;
    ; i<len; i++){
        int idx = str[i]-'a';
        p = p->Next[idx];
        //...进行一系列操作
    }
}

inline void DelTrie(Trie *T)
{
    if(T == NULL) return ;
    ; i<maxn; i++){
        if(T->Next[i] != NULL)
            DelTrie(T->Next[i]);
    }
    free(T);
    return ;
}

int main(void)
{
    root.init();//!!!
    //...
}

指针版

#include<string.h>
#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<algorithm>
using namespace std;
 + ;

struct Trie
{
    int Next[maxn], v;
    inline void init(){
        v = ;
        memset(Next, -, sizeof(Next));
    }
};

]; // 字典树可能最多的节点数,注意开足了!

;

void CreateTrie(char *str)
{
    int len = strlen(str);
    ;
    ; i<len; i++){
        int idx = str[i]-'a';
        int nxt = Node[now].Next[idx];
        ){
            nxt = ++tot;
            Node[nxt].init();
            Node[now].Next[idx] = nxt;
        }else Node[nxt].v++;
        now = nxt;
    }
    // Node[now].v = //尾部标志
}

int FindTrie(char *str)
{
    int len = strlen(str);
    ;
    int nxt;
    ; i<len; i++){
        int idx = str[i]-'a';
        ) now = Node[now].Next[idx];
        ;
    }
    return Node[now].v;//返回该返回的值
}

数组版

字典树算法参考 ==> http://www.cnblogs.com/tanky_woo/archive/2010/09/24/1833717.html

 IOI论文《浅析字母树在信息学竞赛中的应用》 ==> http://www.doc88.com/p-434727490439.html

相关题目 :

HUD 1251

题意 : 给出很多单词(只有小写字母组成,不会有重复的单词出现),要求统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).

分析 : 模板题,直接累加前缀即可

///数组版
#include<string.h>
#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<algorithm>
using namespace std;
 + ;

struct Trie
{
    int Next[maxn], v;
    inline void init(){
        v = ;
        memset(Next, -, sizeof(Next));
    }
};

]; // 字典树可能最多的节点数,注意开足了!

;

void CreateTrie(char *str)
{
    int len = strlen(str);
    ;
    ; i<len; i++){
        int idx = str[i]-'a';
        int nxt = Node[now].Next[idx];
        ){
            nxt = ++tot;
            Node[nxt].init();
            Node[now].Next[idx] = nxt;
        }else Node[nxt].v++;
        now = nxt;
    }
}

int FindTrie(char *str)
{
    int len = strlen(str);
    ;
    int nxt;
    ; i<len; i++){
        int idx = str[i]-'a';
        ) now = Node[now].Next[idx];
        ;
    }
    return Node[now].v;
}

];
int main(void)
{
    Node[].init();
    while(gets(s)){
        ] == '\0') break;
        CreateTrie(s);
    }
    while(scanf("%s", s)!=EOF){
        printf("%d\n",FindTrie(s));
    }
    ;
}

///指针版
#include<string.h>
#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<algorithm>
using namespace std;
;

struct Trie
{
    Trie *Next[maxn];
    int v;
    inline void init(){
        ;
        ; i<maxn; i++)
            this->Next[i] = NULL;
    }
};
Trie *root = (Trie *)malloc(sizeof(Trie));

inline void CreateTrie(char *str)
{
    int len = strlen(str);
    Trie *p = root, *tmp;
    ; i<len; i++){
        int idx = str[i]-'a';

        if(p->Next[idx] == NULL){
            tmp = (Trie *)malloc(sizeof(Trie));
            tmp->init();
            p->Next[idx] = tmp;
        }else p->Next[idx]->v++;

        p = p->Next[idx];
    }
    //p->v = -1;
}

int FindTrie(char *str)
{
    int len = strlen(str);
    Trie *p = root;
    ; i<len; i++){
        int idx = str[i]-'a';
        if(p->Next[idx] != NULL) p = p->Next[idx];
        ;
    }
    return p->v;
}

inline void DelTrie(Trie *T)
{
    if(T == NULL) return ;
    ; i<maxn; i++){
        if(T->Next[i] != NULL)
            DelTrie(T->Next[i]);
    }
    free(T);
    return ;
}
];
int main(void)
{
    root->init();
    while(gets(s)){
        ] == '\0') break;
        CreateTrie(s);
    }

    while(scanf("%s", s)!=EOF){
        printf("%d\n",FindTrie(s));
    }DelTrie(root);
    ;
}

HDU 2846

题意 : 给出 P 个单词和 Q 个询问,对于每一次询问给出询问串是多少个 P 中字符的子串

分析 : 利用KMP的话可以做,但是复杂度爆炸,可以利用字典树,将 P 个单词的每一个以及其子串全部丢去建树,最后问询串直接去跑字典树查询即可。但是在字典树上权值的累加需要注意,例如 abb 这个串,在分解的时候 b 即属于 bb 也属于 b 那么当问询 b 这个字符串的时候就应该输出 2 吗?很显然不是,对于当前分解的串,我们需要给它加一个 id 来判断当前的字符是否是由同一个串分解而来的,就能避免重复计算。

#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<malloc.h>
using namespace std;
;

struct Trie{ Trie *Next[maxn]; int v, who; };
Trie *root = (Trie *)malloc(sizeof(Trie));

void CreateTrie(char *str, int who)
{
    int len = strlen(str);
    root->who = who;
    ; st<=len-; st++){
        Trie *p = root, *tmp;
        for(int i=st; i<len; i++){
            int id = str[i] - 'a';

            if(p->Next[id]==NULL){
                tmp = (Trie *)malloc(sizeof(Trie));
                tmp->v = ;
                tmp->who = who;
                ; j<maxn; j++)
                    tmp->Next[j] = NULL;

                p->Next[id] = tmp;
                p = p->Next[id];

            }else{
                if(who != p->Next[id]->who) {
                    p->Next[id]->v++;
                    p->Next[id]->who = who;
                }
                p = p->Next[id];
            }
        }
    }

}

;

bool TrieFind(int n, char *str) //代码将演示在树上找str的前缀是否存在
{
    ans = ;
    int len = strlen(str);
    Trie *p = root;
    ; i<len; i++){
        int id = str[i] - 'a';
        if(p->Next[id] != NULL) p = p->Next[id];
        else return false;
    }
    ans = p->v;
    return true;
}

inline void DelTrie(Trie *T)
{
    int i;
    if(T == NULL) return ;
    ; i<maxn; i++){
        if(T->Next[i] != NULL){
            DelTrie(T->Next[i]);
        }
    }
    free(T);
    return ;
}
];
int main(void)
{
    ; i<maxn; i++) root->Next[i] = NULL;
    root->who = -;
    root->v = ;
    int n, q;
    scanf("%d", &n);
    ; i<n; i++){
        scanf("%s", str);
        CreateTrie(str, i);
    }
    scanf("%d", &q);
    ; i<q; i++){
        scanf("%s", str);
        if(TrieFind(n, str)) printf("%d\n", ans);
        ");
    }
    DelTrie(root);
    ;
}

字典树模板( 指针版 && 数组版 )的更多相关文章

  1. 字典树模板 HDU - 1251

    题意: 给一些单词,换行键后,查找以后输入的单词作为前缀的话们在之前出现过几次. 思路: 字典树模板----像查字典的顺序一样 #include<string> #include<s ...

  2. hdu1521(字典树模板)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1251 题意: 中文题诶~ 思路: 字典树模板 代码1: 动态内存, 比较好理解一点, 不过速度略慢, ...

  3. 【统计难题】【HDU - 1251】【map打表或字典树】【字典树模板】

    思路 题意:题目为中文题,这里不再过多阐述. 思路1:可以在读入单词表的过程中将单词分解,用map将它一 一记录 思路2:利用字典树,这个方法较快些,下面代码中会分别给出数组和结构体指针两种形式的字典 ...

  4. HDU - 1251 字典树模板题

    Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).  Input输入数据的第一部 ...

  5. 字典树模板题(统计难题 HDU - 1251)

    https://vjudge.net/problem/HDU-1251 标准的字典树模板题: 也注意一下输入方法: #include<iostream> #include<cstdi ...

  6. CH 1601 - 前缀统计 - [字典树模板题]

    题目链接:传送门 描述给定 $N$ 个字符串 $S_1,S_2,\cdots,S_N$,接下来进行 $M$ 次询问,每次询问给定一个字符串 $T$,求 $S_1 \sim S_N$ 中有多少个字符串是 ...

  7. HDU:1251-统计难题(字典树模板,动态建树,静态建树)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1251 统计难题 Time Limit: 4000/2000 MS (Java/Others) Memor ...

  8. P1184 高手之在一起(字典树模板题,hash算法, map)

    哎,唯一值得说明的是,这道题的输入有bug 先把字典树的算法模板放一下 #include<iostream> #include<cstring> using namespace ...

  9. hdu 1671 Phone List 字典树模板

    Given a list of phone numbers, determine if it is consistent in the sense that no number is the pref ...

随机推荐

  1. Linux iptables 防火墙常用规则

    iptables 安装 yum install iptables iptables 规则清除 iptables -F iptables -X iptables -Z 开放指定的端口允许本地回环接口(即 ...

  2. cocos2dx基础篇(11) 点九图CCScale9Sprite

    [3.x] (1)去掉"CC" [v3.3] 我们在 ui模块 下实现了一个新的Scale9Sprite类.它的内部实现比之前的Scale9Sprite更为简洁,功能也更为强大. ...

  3. 精读《Optional chaining》

    1. 引言 备受开发者喜爱的特性 Optional chaining 在 2019.6.5 进入了 stage2,让我们详细读一下草案,了解一下这个特性的用法以及讨论要点. 借着这次精读草案,让我们了 ...

  4. linux 扩展正则表达式 egrep

    使用命令为grep -E 及egrep [root@MongoDB ~]# cat mike.log I am mike! I like linux. I like play football, te ...

  5. SQL Server之索引解析(二)

    1.堆表 堆表通过IAM连接一起,查询时全表扫描. 1.1 非聚集索引 结构 叶子节点数据结构:行数据结构+Rid(8字节) 中间节点数据结构: (非聚集非唯一索引)行数据结构+Page(4)+2+ ...

  6. java 异常体系详细介绍

    一.异常概述与异常体系结构 异常:在Java语言中,将程序执行中发生的不正常情况称为"异常".(开发过程中的语法错误和逻辑错误不是异常). Java把异常当作对象来处理,并定义一个 ...

  7. Luogu P1084 [NOIP2012]疫情控制

    题目 首先我们二分一下答案. 然后我们用倍增让军队往上跳,最多先跳到根的子节点. 如果当前军队可以到达根节点,那么记录一下它的编号和它到达根节点后还可以走的时间. 并且我们记录根节点的叶子节点上到根节 ...

  8. 数学: HDU1098 Ignatius's puzzle

    Ignatius's puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  9. oracle数据库中的存储过程

    存储过程是一组为了完成特定功能的sql语句集,是一段sql代码片段,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果存储过程存在参就给出,不存在就不用给出参数)来执行它.因为它是一段 ...

  10. vue.js table组件封装

    table组件 和 分页组件来自iview,在这里我根据公司业务再次做了一次封装,使用slot进行内容分发,可以随意放置input输入框和button按钮 ,再使用props向子组件传递参数,使用em ...