其他分享
首页 > 其他分享> > 字典树trie

字典树trie

作者:互联网

字典树

  又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

字典树如何建树

  如he,she,his,her,hers五个单词,如何建立一颗字典树。其实就是利用公共前缀前缀相同的部分放在同一个存储单元内。(如下图,蓝色节点表示该节点为单词节点)

  1.建立根节点

  2.插入第一个单词,没插入一个单词都从根节点开始查找看当前节点是否存在这个字母的边,如果不存在,建立新节点。如插入he时,从根节点开始搜索,根节点没有连接h边,所以建立新节点,新的节点没有连接e边,所以再建新节点,因为e时单词的最后一个字母,所以标记这个节点为单词节点。

  3.插入his是发现根节点连接着h边所以我们沿着h边搜索,发下下一个节点没有连接i边,所以继续2操作。

  4.建图完成

代码:

  这里以hdu1004为列子写了一个ac了题目的代码,只用到了插入的操作。查找的操作和插入极其相似,都是从根节点开始,只需要稍加修改即可。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>

using namespace std;

const int maxnode=15000+10;
const int sigma_size=30;

struct trie {
    int ch[maxnode][sigma_size];
    int val[maxnode];
    int vis[maxnode];
    char sh[maxnode][sigma_size];
    int sc;
    int sz;

    trie(){
        sz=1;
        sc=1;
        memset(ch[0],0,sizeof(ch[0]));
    }
    int idx(char c){return c-'a';}

    void f(char *s){
        int u=0,n=strlen(s);
        for(int i=0;i<n;i++){
            int c=idx(s[i]);
            if(!ch[u][c]){
                memset(ch[sz],0,sizeof(sz));
                val[sz]=0;
                ch[u][c]=sz++;
            }
            u=ch[u][c];
        }
        val[u]++;
        if(val[u]==1){
            strcpy(sh[sc],s);
            vis[u]=sc;
            sc++;
            //printf("....%d",sc);
        }
    }

    void g(){
        int maxn=0;
        int maxnn=0;
        for(int i=0;i<sz;i++){
            if(val[i]!=0)
            if(maxn<val[i]){
                maxn=val[i];
                maxnn=vis[i];
            }
        }
        printf("%s\n",sh[maxnn]);
    }

    void fff(){
        for(int i=0;i<sz;i++){
            printf("%d %d ",val[i],vis[i]);
            for(int j=0;j<sigma_size;j++){
                printf("%d",ch[i][j]);
            }
            printf("\n");
        }
        for(int i=0;i<sc;i++){
            printf("%s\n",sh[i]);
        }
    }
};
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        getchar();
        if(n==0)break;
        trie aa;
        char aaa[20];
        for(int i=0;i<n;i++){
            scanf("%s",aaa);
            aa.f(aaa);
        }
        aa.g();
        //aa.fff();
    }
    return 0;
}

 

标签:插入,trie,maxnode,单词,int,include,节点,字典
来源: https://www.cnblogs.com/wz-archer/p/10732196.html