zoukankan      html  css  js  c++  java
  • 静态字典树和动态字典树模板

    以前做字典树一直用动态的字典树,每次开辟新空间,需要 new ,删除时delete, 这样动态,节省内存,却要每次开辟和释放空间,饿很难浪费时间,

    静态字典树, 是事先开辟一块足够的空间,需要时区取,计较节省时间,有时候却浪费了不必要的内存,写静态字典树,可以开二维数组,也可以用结构体加上指针;

    结构体 静态字典树模板

    #define  MAX    26 //字符集大小
    
    typedef struct TrieNode
    {
        int nCount; //记录该字符出现次数
        struct TrieNode *next[MAX];
    }TrieNode;
    
    TrieNode Memory[1000000];
    int allocp = 0;
    
    /*初始化*/
    void InitTrieRoot(TrieNode **pRoot)
    {
        *pRoot = NULL;
    }
    
    /*创建新结点*/
    TrieNode *CreateTrieNode()
    {
        int i;
        TrieNode *p;
    
        p = &Memory[allocp++];
        p->nCount = 1;
        for(i = 0 ; i < MAX ; i++)
        {
            p->next[i] = NULL;
        }
    
        return p;
    }
    
    /*插入*/
    void InsertTrie(TrieNode **pRoot , char *s)
    {
        int i , k;
        TrieNode *p;
    
        if(!(p = *pRoot))
        {
            p = *pRoot = CreateTrieNode();
        }
        i = 0;
        while(s[i])
        {
            k = s[i++] - 'a'; //确定branch
            if(p->next[k])
                p->next[k]->nCount++;
            else
                p->next[k] = CreateTrieNode();
            p = p->next[k];
        }
    }
    
    //查找
    int SearchTrie(TrieNode **pRoot , char *s)
    {
        TrieNode *p;
        int i , k;
    
        if(!(p = *pRoot))
        {
            return 0;
        }
        i = 0;
        while(s[i])
        {
            k = s[i++] - 'a'; 
            if(p->next[k] == NULL)    return 0;
            p = p->next[k];
        }
        return p->nCount;
    }
    
    

     动态字典树模板

    //专题地址http://vjudge.net/vjudge/contest/view.action?cid=51317#overview 此为动态字典树,静态字典树可自学。
    #include <iostream>
    #include <cstdio>
    #include <string.h>
    using namespace std;
    typedef struct DT
    {
        DT *chid[52];
        int end;
        DT()
        {
            end=0;
            memset(chid,0,sizeof(chid));
        }
    }dt,*pdt;
    pdt root;//定义根节点
    int getnum(char s) //根据字符得到num
    {
        if(s>='A'&&s<='Z')return s-'A';
        else return s-'a'+26;
    }
    void insert(char *s) //插入字符串到字典树
    {
        pdt next=root;
        int num;
        for(int i=0;s[i];i++)
        {
            num=getnum(s[i]);
            if(next->chid[num]==NULL) //为空则申请内存
                next->chid[num]=new DT(); //开辟内存
            next=next->chid[num];
        }
        next->end=1; //字符串最末尾end赋值true
        return ;
    }
    int query(char *s) //查询字符串在字典树
    {
        pdt next=root;
        int num;
        for(int i=0;s[i];i++)
        {
            num=getnum(s[i]);
            if(next->chid[num]==NULL) //没有此地址,返回未找到
                return 0;
            next=next->chid[num]; //继续查找
        }
        if(next->end) return 1; //找到返回true
        return 0;
    }
    void del(dt *rot) //递归删除字典树
    {
        for(int i=0;i<52;i++)
            if(rot->chid[i]!=NULL)
                del(rot->chid[i]);
        delete rot;
    }
    char str[50002][50];
    int main()
    {
        root=new DT(); //根节点分配内存
        char a[]={"nihaoa"};
        insert(a);
        printf("%d %d
    ",query("nihaoa"),query("wobuhao")); //nihaoa存在 返回1 wobuhao不存在 返回0
        del(root); //删除字典树
        return 0;
    }


    
    
    
    

    www.cnblogs.com/tenlee
  • 相关阅读:
    opencv-活体检测
    人脸识别
    Opencv-python基本操作
    白话深度学习与Tensorflow(二)
    Linux系统入门(一)-未完成
    编程题29 题目:求对角线元素之和
    编程题28 题目 排序
    编程题27 题目:求100之内的素数
    编程题 18兵乓球比赛
    编程题21 求阶数总和
  • 原文地址:https://www.cnblogs.com/tenlee/p/4420137.html
Copyright © 2011-2022 走看看