模板 : 

#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. 一文学会Go - 2 数据结构与算法实践篇

    练习:使用go语言实现冒泡排序和归并排序 冒泡排序是所有排序算法中最简单的,练习时先实现它: func bubbleSort(array []int) { n := len(array) ; j &l ...

  2. vue组件事件(极客时间Vue视频笔记)

    vue组件核心:事件 <body> <div class="app"> <todo-list></todo-list> {{mess ...

  3. RocketMQ事务性消息及持久化

    TransactionProducer(事务消息): 在分布式系统中,我们时常会遇到分布式事务的问题,除了常规的解决方案之外,我们还可以利用RocketMQ的事务性消息来解决分布式事务的问题.Rock ...

  4. 首次全备及事务备份对数据库的影响,2014 SpexSql log评估版探索

    参考:https://www.cnblogs.com/gered/p/9882367.html 关键词:解析事务日志 新建数据库test3,然后查看日志文件,382行记录 SELECT min([Be ...

  5. Oracle Replace函数的简单使用

      REPLACE ( char, search_string [, replace_string]) 如果没有指定replace_string 变量的值,那么当发现search_string 变量的 ...

  6. Highways POJ-1751 最小生成树 Prim算法

    Highways POJ-1751 最小生成树 Prim算法 题意 有一个N个城市M条路的无向图,给你N个城市的坐标,然后现在该无向图已经有M条边了,问你还需要添加总长为多少的边能使得该无向图连通.输 ...

  7. P1754球迷购票问题

    这是一道动态规划题,其实也是个数论题. 有n人拿50,有n人拿100买票,必须让50元的人买,不然无法找零钱,问最多有几种方案可以每一次都买票成功.这个题首先令人想到搜索,但是随即发现dp是正解,于是 ...

  8. hive中的索引创建

    1.在hive中创建索引所在表 create table if not exists h_odse.hxy(id int,name string,hobby array<string>,a ...

  9. HNUSTOJ-1009 格雷码

    1009: 格雷码 时间限制: 1 Sec  内存限制: 128 MB提交: 90  解决: 78[提交][状态][讨论版] 题目描述 对于给定的正整数n,格雷码为满足如下条件的一个编码序列:(1) ...

  10. object in javascript

    枚举对象属性 for....in 列举obj的可枚举属性,包括自身和原型链上的 object.keys() 只列举对象本身的可枚举属性 创建对象的几种方式 对象字面量 const pre='test' ...