• CH601后缀数组【Trie树】


    内含字典树创建及查询模板

    1601 前缀统计 0x10「基本数据结构」例题

    描述

    给定N个字符串S1,S2...SN,接下来进行M次询问,每次询问给定一个字符串T,求S1~SN中有多少个字符串是T的前缀。输入字符串的总长度不超过10^6,仅包含小写字母。

    输入格式

    第一行两个整数N,M。接下来N行每行一个字符串Si。接下来M行每行一个字符串表示询问。

    输出格式

    对于每个询问,输出一个整数表示答案

    样例输入

    3 2
    ab
    bc
    abc
    abc
    efg
    

    样例输出

    2
    0

    思路:

    用scanf !=EOF最后一组不知道为什么就是会RE

    虐狗宝典字典树笔记:

    Trie树,字典树每个节点拥有若干个字符指针,在插入或检索字符串时扫到一个字符c就沿着当前节点的c字符指针走下去。

    初始时,空Trie仅包含一个根节点,字符指针均为空。

    插入S时,我们令一个指针p指向根节点,依次扫描S中的每一个字符c。

      1.若p的c字符指针指向一个已经存在的节点Q,则令P=Q

      2.若p的c字符指针指向空,则新建一个节点Q,令p的c字符指针指向Q,然后令P=Q

      当S扫描完毕,当前节点P上标记他是一个字符串的末尾

    检索S是否在Trie中存在,令一个指针P指向根节点,依次扫描S中的每个字符c

      1.若P的c字符指针指向空,则说明S没有被插入过Trie,结束检索

      2.若P的c字符指针指向一个已经存在的节点Q,则令P=Q

      当S中的字符扫描完毕,若当前节点P被标记为一个字符串的末尾,说明S在Trie中存在。

    本题与讲解的不同之处在于末尾应标记出现的次数,检索时也应该同时统计所经过节点的作为末尾的次数。

     1 #include <iostream>
     2 #include <set>
     3 #include <cmath>
     4 #include <stdio.h>
     5 #include <cstring>
     6 #include <algorithm>
     7 #include <map>
     8 using namespace std;
     9 typedef long long LL;
    10 #define inf 0x7f7f7f7f
    11 
    12 int n, m;
    13 const int maxn = 1e6 + 10;
    14 int trie[maxn][26], tot = 1, ed[maxn];
    15 char s[maxn];
    16 
    17 void insertt(char *str)
    18 {
    19     int len = strlen(str), p = 1;
    20     for(int k = 0; k < len; k++){
    21         int ch = str[k] - 'a';
    22         if(trie[p][ch] == 0){
    23             trie[p][ch] = ++tot;
    24         }
    25         p = trie[p][ch];
    26     }
    27     ed[p]++;
    28 }
    29 
    30 int searchh(char* str)
    31 {
    32     int ans = 0;
    33     int len = strlen(str), p = 1;
    34     for(int k = 0; k < len; k++){
    35         
    36         p = trie[p][str[k] - 'a'];
    37         if(p == 0)return ans;
    38         ans += ed[p];
    39     }
    40     //ans += ed[p];
    41     return ans;
    42 }
    43 
    44 int main()
    45 {
    46     scanf("%d%d", &n, &m);
    47 
    48     for(int i = 1; i <= n; i++){
    49         scanf("%s", s);
    50         insertt(s);
    51     }
    52     for(int j = 1; j <= m; j++){
    53         scanf("%s", s);
    54         printf("%d
    ", searchh(s));
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    数学角度看设计模式之观察者模式
    XML、JSON数据结构解析
    [理解ASP.NET Core框架]一个五十行的控制台Web
    .Net Core 学习 (1)
    SqlServer windowss身份登陆和sa身份登陆
    学习51单片机——秒表分享
    C语言中函数声明实现的位置
    java DOM4J 读取XML
    服务器与Linux操作系统基础原理
    Go语言实现数据结构(一)单链表
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9824073.html
Copyright © 2020-2023  润新知