• 字典树的动态与静态模板


    动态链表:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstring>
     
    using namespace std;
     
    struct Node
    {
        Node * child[10];
        bool bad;
        Node()    //构造函数中初始化。在静态分配时就能初始化。
        {
            memset(child, 0, sizeof(child));
            bad = false;
        }
    };
    int nodeCount;  //用来指向数组中未分配的单元。
    bool insertNode(Node *tree, char *s)
    {
        int i;
        Node * p = tree;
        for(i = 0; s[i+1]; i++)
        {
            if(p->child[s[i]-'0'] == 0)
            {
                p->child[s[i]-'0'] = tree + nodeCount; //将各个节点按次序分配到数组的相应位置。
                nodeCount++;
            }
            p = p->child[s[i]-'0'];
            if(p->bad)    //如果遇到危险节点(某个字符串的最后一个节点),则说明该串含有前面的串。
            {
                return false;
            }
        }
        bool ok;
        if(p->child[s[i]-'0'] == 0)
        {
            p->child[s[i]-'0'] = tree + nodeCount;
            nodeCount++;
            ok = true;
        }
        else    //如果最后一个节点已经被分配过,说明该串是前面串的前缀。
            ok = false;
       
        p = p->child[s[i]-'0'];
        p->bad = true;  //字符串最后一个节点是危险节点。
        return ok;
    }
    void del(Node *p)
    {
        for(int i=0;i<10;i++)
        {
            if(p->child[i])
                del(p->child[i]);
        }
        delete(p);
    }
    Node Tree[100000];  //为了避免初始化,直接重新开,分配大小要合适,否则RA。
    int main()
    {
        int n, i, t;
        bool ok;
        scanf("%d", &t);
        while(t--)
        {
            scanf("%d", &n);
            char s[12];
            memset(Tree,0,sizeof(Tree));
            nodeCount = 1;
            ok = true;
            for(i = 0; i < n; i++)
            {
                scanf(" %s", s);
                if(!insertNode(Tree, s))
                {
                    ok = false;
                }
            }
            if(ok)
                printf("YES
    ");
            else
                printf("NO
    ");
        }
        return 0;
    }
    

     静态数组模拟模板:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int M = 33333;
    const int N = 27;
    char st[M][N];
    int tot,size,sz;
    int trie[M*10][N],num[10*M];
    void insert(char *st){
        int len=strlen(st+1);
        int now=0;
        for(int i=1;i<=len;i++){
            int k=st[i]-'a';
            if(trie[now][k]==0) trie[now][k]=++sz;
            now=trie[now][k];
            num[now]++;
        }
    }
    void ask(char *st){
        int now=0,k,len=strlen(st+1);
        for(int i=1;i<=len;i++){
            if(num[now]==1) break;
            k=st[i]-'a';
            printf("%c",st[i]);
            now=trie[now][k];
        }
    }
    int main(){
        while(~scanf("%s",st[++tot]+1))
            insert(st[tot]);
        for(int i=1;i<=tot;i++){
            printf("%s ",st[i]+1);
            ask(st[i]);
            printf("
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    不怕上不了 Android developers
    不花钱的可靠性设计
    linux2.6 内核特性配置
    Linux动态库的编译与使用 转载
    多线程使用互斥锁的C范例
    TSLIB 分析
    Notepad++中文版下载 以及HEX显示
    C程序实现在lcd 上全屏写 blue 色 及获取fb信息
    pthread_cond_wait的spurious wakeup问题
    查看linux内存条数的命令与清理内存使用
  • 原文地址:https://www.cnblogs.com/zmin/p/7353582.html
Copyright © 2020-2023  润新知