自制简单Trie树

  本来想用vector来写一个更方便的版本来着,但是考虑到效率问题和现场编写的复杂程度问题觉得还是算了……

  简单介绍下字典树吧。

  问这么一个问题:给出很多很多很多的字符串,如何查询某一字符串是否存在?这个好说,用哈希嘛,数据结构课上教的。

  那把这个问题加强一下:给出很多很多很多的字符串,如何查询前缀为s的字符串是否存在或者有多少个?这个用哈希就不好整了,但是用字典树就比较好实现。

  字典树也是树形结构的一种,最基本的形态看上去就是下面图的这个样子。它是基于这么一个思路,比如我要查abcd,那么我先查有没有a开头的字符串,然后在a开头的字符串中查有没有b是第二个字符的,然后以此类推一直查完。当然这些结点上还可以附上信息以实现别的目的,比如它是第几个出现的啊,或者它是不是个完整的单词啊,诸如此类。



  代码就在下面了,这只是个十分简单的版本,只有一个插入和查询操作。

#include 
   
   
    
    
#include 
    
    
     
     
class Trie {
private:
    static const int T_MAXSIZE = 20000000; // 字典树的容量
    static const int T_NEXTSIZE = 10; // 字典树每个节点有多少个子节点
private:
    int node[T_MAXSIZE];
    int next[T_MAXSIZE][T_NEXTSIZE];
    int size;
public:
    Trie() : size(0) {
        node[size] = 0;
        memset(node, 0, sizeof(node));
        memset(next, 0, sizeof(next));
    }
private:
    int ID(const char &c) { 
        // to do...
    } // 传入的参数对应某一结点的第几个子结点
    int newnode() { return size += 1; } // 创建新结点
public:
    void insert(char *s, int l, int id) { // 将字符串s的前l个字符放入字典树,附在结点上的信息为ID
        int cur = 0;
        for(int i = 0; i != l; ++i) {
            const int num = ID(s[i]);
            if(!next[cur][num]) {
                int pt = newnode();
                next[cur][num] = pt;
                node[pt] = id;
            }
            cur = next[cur][num];
        }
        if(!node[cur]) node[cur] = id;
    }
    int query(char *s) { // 查询字符串s是否在字典树中,如果在,返回附在结点上的信息
        int cur = 0;
        for(int i = 0; s[i]; ++i) {
            const int num = ID(s[i]);
            if(!next[cur][num]) return -1;
            cur = next[cur][num];
        }
        return node[cur];
    }
};

    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值