字典树(trie)

这个模板是查询字串出现次数的

举个例

a

ab

abc

abcd

则a出现了4次,b出现了3次,c出现了2次,d出现了一次。

字典树的操作都大同小异,所以要牢记此模板。

#include<bits/stdc++.h>
using namespace std;

const int maxn=10001;

struct Trie//初始化,加点,加字串,查询字串 
{
    int ch[maxn][26];//记录每个结点的子节点编号(编号从0开始) 
    int cnt[maxn];//记录字串出现次数
    int num;//顺序结点编号直到最后一个结点 
    
    void clean()//初始化 
    {
        memset(ch,0,sizeof(ch));
        memset(cnt,0,sizeof(cnt));
        cnt[0]=0;
        num=0;
    }//一起初始化防止被hack 
    
    int newnode()//添加新节点 
    {
        num++;//编号加
        return num;//返回编号 
    }
    
    void insert(string s)//读入字符串后从头开始向下比较,没有就添加 
    {
        int u=0;
        int n=s.size();
        for(int i=0;i<n;i++)
        {
            if(ch[u][s[i]-'a']==0)
            {
                ch[u][s[i]-'a']=newnode();
            }
            u=ch[u][s[i]-'a'];//更新到下一个结点
            cnt[u]++;//下个结点++(从0结点开始) 
        }
    }
    
    int query(string s)//读入字符串后从头开始向下查询,没有就返回0 
    {
        int u=0;
        int n=s.size();
        for(int i=0;i<n;i++)
        {
            if(ch[u][s[i]-'a']==0) return 0;//没找到 
            u=ch[u][s[i]-'a'];
        }
        return cnt[u];//返回出现次数 
     } 
}trie;

int main()
{
    trie.clean();//记得初始化!!! 
    trie.insert("a");
    trie.insert("ab");
    trie.insert("abc");            
    trie.insert("abcd");
    cout<<trie.query("a")<<endl<<trie.query("ab")<<endl<<trie.query("abc")<<endl<<trie.query("abcd");
    cout<<endl;
    return 0;
}

 

posted @ 2018-10-29 22:15  前排吃瓜  阅读(175)  评论(0编辑  收藏  举报