Trie

Trie 字典树的实现

Trie 又叫字典树、前缀树,属于一种高级排序树。它主要用来保存字符串集。


Trie

上图所示即为一颗Trie,标识的字符串集合为{a,to,tea,ted,ten,i,in,inn},每个单词的结束位置对应一个“单词结点”。反过来,从根节点到每个单词结点的路径上所有的字符连接起来就是这个结点对应的字符串。我们可以将根结点标为0(注意,根结点不保存任何字符),其余结点从1开始标号(正整数),这样就可以用数组来存了。(当然,也可以不这么做,使用链表存储)

在这里,我们可以用ch[i][j]表示节点i对应的ASCII码为j的那个字符的子结点,如果这个子结点不存在,让ch[i][j]=0(这样并不会引起歧义,因为任何结点的子结点不可能是根结点)。然而,利用Trie时,我们往往需要给结点加上一些附加信息,比如:从根到该结点处的字符串是否可以表示一个单词、该单词的中文翻译等等,我们把这个附加信息保存在val[i]中即可。

那么,代码就很显然了

插入:

void insert(char *s,int v){
    int u=0,n=strlen(s);
    for (int i=0;i<n;i++){
        int c=idx(s[i]);
        if (!ch[u][c]){ //结点不存在
            ch[u][c]=create(); 
        }
        u=ch[u][c]; //往下走
    }
    val[u]=v
}

以下是利用Trie实现词典的查询和插入操作:

#include<iostream>
#include<cstring>
using namespace std;

const int maxn=1001,sigma_size=127;

struct trie{
    trie(){ //初始化
        memset(ch,0,sizeof(0));
        memset(val,0,sizeof(val));
        sz=1;
    }
    private:
        int ch[maxn][sigma_size],sz; //sz 为结点总数
        char val[maxn][maxn];
        int idx(char t){return (int)t;}
        int create(){ //新建结点
            memset(ch[sz],0,sizeof(ch[sz]));
            memset(val[sz],0,sizeof(val[sz]));
            return sz++; 
        }
    public:
        void insert(char *s,char* v){ //插入
            int u=0,n=strlen(s);
            for (int i=0;i<n;i++){
                int c=idx(s[i]);
                if (!ch[u][c]){ //结点不存在
                    ch[u][c]=create(); 
                }
                u=ch[u][c]; //沿着路径往下走
            }
            memcpy(val[u],v,sizeof(v)); //将v中的值保存在val[u]中,如果是int类型,将val定义为int[],这里就只需要val[u]=v
        }
    char* query(char *s){ //查询
            bool flag=true;
            int u=0,n=strlen(s);
            for (int i=0;i<n;i++){
                int c=idx(s[i]);
                if (!ch[u][c]) { //结点不存在,即没查到
                    flag=false;
                    break;
                }
                u=ch[u][c]; //往下走
            }
            return (flag&&val[u]!=NULL)?val[u]:NULL; //如果val[u]=NULL代表从根到该结点不是个单词
        }
};

int main(){
    trie x;
    char *p=new char[100];
    char *t=new char[100];
    int k,m;
    cin>>k>>m;
    while (k--){
        scanf("%s%s",p,t);
        x.insert(p,t); //插入
    }
    while (m--) {
        scanf("%s",p); //查询
        printf("%s\n",x.query(p));
    }
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值