模板 : 

#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. 求方程x1+x2+x3=15的整数解的数目

    求方程x1+x2+x3=15的整数解的数目要求0≤x1≤5,0≤x2≤6,0≤x3≤7.解:令N为全体非负整数解(x1,x2,x3),A1为其中x1≥6的解:y1=x1-6≥0的解:A2为其中x2≥7 ...

  2. if you wanna the rainbow, you have to deal with the rain.

    bulk. n. 大量 reluctant. adj. 不情愿的 terrorist. n. 恐怖分子 recognition. n. 认出 tout.v. 兜售 conceal.v. 隐藏 dras ...

  3. Flask(六)—— 自定义session

    Flask(六)—— 自定义session import uuid import json from flask.sessions import SessionInterface from flask ...

  4. Balanced Binary Tree(平衡二叉树)

    来源:https://leetcode.com/problems/balanced-binary-tree Given a binary tree, determine if it is height ...

  5. SpringBoot 使用 RestTemplate 调用exchange方法 显示错误信息

    SpringBoot使用RestTempate SpringBoot使用RestTemplate摘要认证 SpringBoot使用RestTemplate基础认证 SpringBoot使用RestTe ...

  6. 2019 我的世界多了一个 Python

    大一时学过 C语言,大三时用 C 控制单片机,之后就没有别的和编程的交集了. 大约十天前下定决心学 Python,不开玩笑,版本我选 3. 其实我也不是 100% 的零基础,因为一方面,我学过 C:另 ...

  7. SparkStreaming DStream转换

    1.无状态转换操作 (1)无状态转化操作就是把简单的RDD转化操作应用到每个批次上,也就是转换DStream中的每一个RDD. 部分无状态转化操作: (2)尽管这些函数韩起来像作用在整个流上一样,但事 ...

  8. 数据库与前端与Django目录

    数据库 [怀心抱素]初步认识数据库 [怀心抱素]mysql的表操作 [怀心抱素]mysql记录操作 [怀心抱素]mysql索引与补充 [怀心抱素]python操作mysql 前端 [怀心抱素]HTML ...

  9. bootstrap中的横的列

    col-md-6都是可以嵌套的,所以12列都是虚拟的 所以bootstrap是怎么完成的?都是通过绝对的像素值吗?还是自动计算出了本区域的像素数,然后设置的? 看样子应该是后者,所以整个bootstr ...

  10. 初学ctypes:打开进程并返回相关信息

    直接上代码: 1. my_debugger_defines.py 定义相关结构体(在后面创建进程及返回信息时,传参可用到) from ctypes import * # Let's map the M ...