zoukankan      html  css  js  c++  java
  • HDU 5687 Problem C

    度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:

    1、insert : 往神奇字典中插入一个单词

    2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词

    3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串

    Input
    这里仅有一组测试数据。第一行输入一个正整数N(1≤N≤100000),代表度熊对于字典的操作次数,接下来N行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: insert, delete 或者 search)。第二个字符串代表了相关操作后指定的那个字符串,第二个字符串的长度不会超过30。第二个字符串仅由小写字母组成。

    Output
    对于每一个search 操作,如果在度熊的字典中存在给定的字符串为前缀的单词,则输出Yes 否则输出 No。

    Sample Input
    5
    insert hello
    insert hehe
    search h
    delete he
    search hello

    Sample Output
    Yes
    No

     sol:Trie的基本操作

    插入时,记录下单词中每个字符出现的次数;

    删除时,先在Trie中统计以该单词作为前缀的单词个数num,如果num>0,则删除这些单词。删除操作具体为,从根出发,每走到一个结点,该结点出现的次数-num,走到尾结点时,该结点被经过的次数清0,同时,该结点下连接的字符全部清0,即清空子结点。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 #define ll long long
     7 const int maxn = 1e6+5;
     8 const int inf = 0x3f3f3f3f;
     9 struct node
    10 {
    11     int next[26];
    12     int val;
    13 }t[maxn];
    14 char f[20], s[50];
    15 int rt = 1;
    16 int num;
    17   
    18 void insert() 
    19 {
    20     int u = 0, v;
    21     int len = strlen(s+1);
    22     for(int i = 1; i <= len; i++)
    23     {
    24         v = s[i] - 'a';
    25         if (!t[u].next[v]) 
    26             t[u].next[v] = rt++;
    27         u = t[u].next[v]; 
    28         t[u].val++;//这个结点经过的次数+1 
    29     } 
    30 }
    31   
    32 void del() 
    33 {
    34     int u = 0, v;
    35     int len = strlen(s+1);
    36      
    37     for(int i = 1; i <= len; i++)
    38     {
    39         v = s[i] - 'a'; 
    40         u = t[u].next[v]; 
    41         t[u].val -= num;//删除时,每个结点经过的次数-num
    42         //可能还有别的单词的长度是小于该前缀的 
    43     }
    44     t[u].val = 0;//标记变量清空
    45           
    46     for(int j = 0; j < 26; j++) 
    47     //一定要将其子结点全清空 
    48         t[u].next[j] = 0;
    49 }
    50   
    51 int search() 
    52 {
    53     int u = 0, v;
    54     int len = strlen(s+1);
    55      
    56     for(int i = 1; i <= len; i++)
    57     {
    58         v = s[i] - 'a';
    59         if (!t[u].next[v]) return 0;
    60         u = t[u].next[v];
    61         //if (t[u].val == 0) return 0;
    62     }
    63     return t[u].val;
    64 }
    65   
    66 int main() 
    67 {
    68     
    69     int n;
    70     cin >> n;
    71     memset(t, 0, sizeof(t));
    72     while(n--){
    73         scanf("%s%s", f+1, s+1);
    74         if (f[1] == 'i') 
    75             insert();
    76         else
    77             if (f[1] == 'd') 
    78              {
    79                   num = search();  //统计前缀,num为以该串作为前缀的单词数 
    80                   if (num != 0) 
    81                      del();//删除这些单词 
    82             }
    83         else {
    84             if (search()) cout << "Yes" << endl;
    85             else cout << "No" << endl;
    86         }
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    opensuse tumbleweed中安装code
    树莓派中将caplock映射为esc键
    记录一次奇怪但是很有意义的程序编译警告
    新树莓派系统安装ROS记录
    程序的深挖
    intle官方手册下载
    slax linux的定制
    angular4 *ngFor获取index
    axios post传参后台无法接收问题
    AMD、CMD、CommonJs和 ES6对比
  • 原文地址:https://www.cnblogs.com/cutepota/p/12627605.html
Copyright © 2011-2022 走看看