• 字典树


    字典树

    目录

    字典树又称 Trie 树,是一种树形结构。其典型应用是用于统计和排序大量的字符串(但又不仅限与字符串),也可以快速查找前缀。

    字典树有三个基本性质:

    1.根节点不包含字符,除根节点外的每一个结点都只包含一个字符。

    2.从根节点到某一节点,路径上经过的字符连接起来,为该结点对应的字符。

    3.每个结点的所有子节点包含的字符都不相同。

    上模板:

    建树:

    //对于字符串比较多的要统计个数的,map被卡的情况下,直接用字典树
    //很多题都是要用到节点下标来表示某个字符串
    const int maxn =2e6+5;	//如果是64MB可以开到2e6+5,尽量开大
    int tree[maxn][30];		//tree[i][j]表示节点i的第j个儿子的节点编号
    bool ispoint[maxn];		//表示以该节点结尾是一个单词,也可以开成int型
    int tot;				//总节点数
    void insert_(char *str)
    {
       int  len=strlen(str);
       int root=0;
       for(int i=0;i<len;i++)
       {
           int id=str[i]-'0';
           if(!tree[root][id]) tree[root][id]=++tot;
           root=tree[root][id];
       }
       flagg[root]=true;
    }
    

    查询:

    bool query(char *str)		//查询操作,按具体要求改动
    {
        int len=strlen(str);
        int root=0;
        for(int i=0;i<len;i++)
        {
            int id=str[i]-'0';
            if(!tree[root][id]) return false;
            root=tree[root][id];
        }
        return true;
    }
    

    用完重新初始化(多组样例尤其重要):

    void init()					//最后清空,节省时间
    {
        for(int i=0;i<=tot;i++)
        {
           flagg[i]=false;
           for(int j=0;j<10;j++)
               tree[i][j]=0;
        }
       tot=0;					//RE有可能是这里的问题
    }
    

    AC模板:求以每个单词为前缀的单词个数:

    #include<bits/stdc++.h>
    
    using namespace std;
    const int maxn=2e6+10;
    int tree[maxn][30];
    bool ispoint[maxn];
    int sum[maxn],tot=0;
    char s[15];
    void insert(char *s)
    {
        int len=strlen(s);
        int root=0;                         //tot为结点个数
        for(int i=0;i<len;++i)
        {
            int id=s[i]-'a';
            if(!tree[root][id]) tree[root][id]= ++tot;
            sum[tree[root][id]]++;          //每个结点出现的次数
            root = tree[root][id];
        }
        ispoint[root]=true;
    }
    int query(char *s)
    {
        int len=strlen(s);
        int root = 0;
        for(int i=0;i<len;++i)
        {
            int id=s[i]-'a';
            if(!tree[root][id])     return 0;
            root=tree[root][id];
        }
        return sum[root];
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
    
        memset(sum,0,sizeof(sum));
        memset(ispoint,false,sizeof(ispoint));
        while(cin.getline(s,11))
        {
            if(strlen(s)==0)  break;
            insert(s);
        }
        while(cin>>s)
        {
            cout<<query(s)<<endl;
        }
    
        system("pause");
        return 0;
    }
    
  • 相关阅读:
    编译预处理指令:文件包含指令、宏定义指令、条件编译指令
    多文件协作,extern、static、头文件
    函数间参数传递的3种方式
    函数的定义与调用
    编码标准:ASCII、GBK、Unicode(UTF8、UTF16、UTF32)
    插入字符
    Windows Vista for Developers——第四部分:用户帐号控制(User Account Control,UAC)
    C# 获取QQ好友列表信息的实现
    C# 获取QQ群数据的实现
    QQ登陆功能的实现2
  • 原文地址:https://www.cnblogs.com/StungYep/p/12251925.html
Copyright © 2020-2023  润新知