zoukankan      html  css  js  c++  java
  • 『字典树』Trie字典树算法

    学习Trie前提须知

    (Trie)是一个字符串算法,它能够将很多个字符串映射在一棵树上,并且能够很快的判断一个串是否是另一个串的子串,也能够进行统计字符串出现次数等一些其他的东西,考题出现的频率不高,多作用于AC自动机的前置技能。 (甚至可以在Trie上DP)

    算法内容

    竞赛需要用到的点

    1、(Trie)的结构体数组最好往大里开

    2、(Trie)在字符串的题里受限都比较大,常与(kmp)混合用来进行AC自动机算法

    Trie求字符串是否出现过略讲

    (Trie)字典树,从名字就能看出是一棵树形结构了,每一个子树都是一个字符串或多个字符串。

    (Trie)字典树与其他算法不同,直接从代码入手也许更好理解

    将字符加入字典树

    int tot;
    void trieInsert(char *c, int rt) { //trieInsert(c, 0);
        int len = strlen(c);
        for (int i = 0; i < len; i++) {
            int id = c[i] - 'a';
            if(!trie[rt].son[id]) trie[rt].son[id] = ++tot;
            rt = trie[rt].son[id];
        } trie[rt].have = 1;
    }
    

    将字符串导入 (Trie) 中,从这个代码我们可以得到

    • 根节点为空节点,每个节点最多可以接26个点
    • 每个节点上代表为一个字符,末尾需要打上标记,不然若出现一个以当前字符为真前缀的字符就不好判断了

    判断字符串是否存在

    bool trieFind(char *c, int rt) {
        int len = strlen(c);
        for (int i = 0; i < len; i++) {
            int id = c[i] - 'a';
            if(!trie[rt].son[id]) return false;
            rt = trie[rt].son[id];
        }
    
        if(!trie[rt].have) return false;
    }
    

    思路和上面相同 并无多大改动

    看一道模板题于是他错误的点名开始了

    //#define fre yes
    
    #include <cstdio>
    #include <cstring>
    
    const int N = 800005;
    struct Node {
        int son[26];
        int cnt;
        bool have;
    } trie[N];
    
    int tot;
    void trieInsert(char *c, int rt) {
        int len = strlen(c);
        for (int i = 0; i < len; i++) {
            int id = c[i] - 'a';
            if(!trie[rt].son[id]) trie[rt].son[id] = ++tot;
            rt = trie[rt].son[id];
        } trie[rt].have = 1;
    }
    
    int flag;
    bool trieFind(char *c, int rt) {
        int len = strlen(c);
        for (int i = 0; i < len; i++) {
            int id = c[i] - 'a';
            if(!trie[rt].son[id]) return false;
            rt = trie[rt].son[id];
        }
    
        if(!trie[rt].have) return false;
        if(!trie[rt].cnt) {
            trie[rt].cnt++;
            return true;
        } else {
            flag = 1;
            return true;
        }
    }
    
    int main() {
        static int n, m;
        scanf("%d", &n);
        char c[105];
        for (int i = 1; i <= n; i++) {
            scanf("%s", c);
            trieInsert(c, 0);
        }
    
        scanf("%d", &m);
        for (int i = 1; i <= m; i++) {
            scanf("%s", c);
            if(trieFind(c, 0) && flag == 0) {
                puts("OK");
            } else if(trieFind(c, 0) && flag == 1) {
                flag = 0;
                puts("REPEAT");
            } else puts("WRONG");
        } return 0;
    }
    
    
  • 相关阅读:
    前端之CSS盒模型介绍
    前端之CSS列表及背景类属性
    前端之CSS字体和文本类属性
    流程控制语句
    前端之CSS语法及选择器
    前端之CSS创建的样式
    前端之HTML语法及常用标签
    前端之HTML样式
    网页制作之前端简介
    jQuery(一)、核心
  • 原文地址:https://www.cnblogs.com/Nicoppa/p/11508440.html
Copyright © 2011-2022 走看看