zoukankan      html  css  js  c++  java
  • 字典树

    字典树可以用来快速查找字符串前缀,当然,适当的变下形就可以解决需要很多了。

    从根节点开始,每遇见一个红点就可以组成一个单词。

    节点的建立:

      

     1 struct Nod{
     2     bool is;
     3     Nod *next[26];
     4     Nod(){
     5         is = false;
     6         for(int i = 0; i < 26; i ++){
     7             next[i] = NULL;
     8         }
     9     }
    10 };

    插入:

    1 void mkTrie(Nod *root,char *s){
    2     Nod*p = root;
    3     for(int i = 0; s[i]; i ++){
    4         int a = s[i] - '0';
    5         if(p->next[a]==NULL)p->next[a] = new Nod;
    6         p = p->next[a];
    7     }
    8     p->is = true;
    9 }

    删除:(很多题目有很多组数据,如果不删除释放空间的话,很容易导致Memory Limit Exceeded)

     1 void deleTrie(Nod *p){
     2     if(p == NULL) return;
     3     for(int i = 0; i < 26; i ++){
     4         if(p->next[i] != NULL){
     5             deleTrie(p->next[i]);
     6         }
     7     }
     8     free(p);
     9     return ;
    10 }

    查找:

    1 int find(){
    2     Nod* p = &t;
    3     for(int i = 0; s[i]; i ++){
    4         int a = s[i]-'a';
    5         if(p->next[a]==NULL) return 0;
    6         p = p->next[a];
    7     }
    8     return p->num;
    9 }

    HDU1671 为例。

    大意是求是否有某个数为另外一个树的前缀。

    假设X1X2X3...Xn为Y1Y2Y3...Yn的前缀,那么有两种情况。

    (一):X在Y的后面,这时在插入X时,在Xn这里会有子节点。

    (二):X在Y的前面,这时在插入Y时,在Xn这里会被标记。

    AC代码为:

     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 char str[20];
     5 bool flag;
     6 struct Nod{
     7     bool is;
     8     Nod *next[26];
     9     Nod(){
    10         is = false;
    11         for(int i = 0; i < 26; i ++){
    12             next[i] = NULL;
    13         }
    14     }
    15 };
    16 void mkTrie(Nod *root,char *s){
    17     Nod*p = root;
    18     for(int i = 0; s[i]; i ++){
    19         int a = s[i] - '0';
    20         if(p->next[a]==NULL)p->next[a] = new Nod;
    21         if(p->is){
    22             flag = true;
    23         }
    24         p = p->next[a];
    25     }
    26     p->is = true;
    27     for(int i = 0; i < 26; i ++){
    28         if(p->next[i]!=NULL){
    29             flag = true;
    30             break;
    31         }
    32     }
    33 }
    34 void deleTrie(Nod *p){
    35     if(p == NULL) return;
    36     for(int i = 0; i < 26; i ++){
    37         if(p->next[i] != NULL){
    38             deleTrie(p->next[i]);
    39         }
    40     }
    41     free(p);
    42     return ;
    43 }
    44 int main(){
    45     int T,n;
    46     scanf("%d",&T);
    47     while(T--){
    48         scanf("%d",&n);
    49         Nod *t = new Nod;
    50         flag = false;
    51         for(int i = 0; i < n; i ++){
    52             scanf("%s",str);
    53             if(!flag){
    54                 mkTrie(t,str);
    55             }
    56         }
    57         if(flag)cout << "NO
    ";
    58         else cout << "YES
    ";
    59         deleTrie(t);
    60     }
    61     return 0;
    62 }

      

  • 相关阅读:
    mysql "ON DUPLICATE KEY UPDATE" 语法
    HTTP协议中PUT和POST使用区别
    layui 表单渲染失败
    golang 一行代码 把array/slice转成逗号分隔的字符串
    关于layui、table数据表格请求异常回调函数
    关于layui表单中按钮自动提交的解决方法
    使用 socket.io 报错 Error during WebSocket handshake: Unexpected response code: 400
    解决MySQL报错:[Err] 1055
    jetbrains 修改 http proxy 更换代理
    layui layuiadmin layui.data 数据操作
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/7116855.html
Copyright © 2011-2022 走看看