zoukankan      html  css  js  c++  java
  • Trie树模板 + 例题

    字典树模板

    const int maxn=2e6+5;
    int tree[maxn][55];   //tree[i][j]表示节点i的第j个儿子的节点编号
    bool flagg[maxn];    //表示以该节点结尾的是一个单词
    int tot;    //总结点数
    void insert_(char *str)
    {
        int len=strlen(str);
        int root=0;
        for(int i=0;i<len;i++){
            int id=str[i]-'a';
            if(!tree[root][id])tree[root][id]=++tot;
            root=tree[root][id];
        }
        flagg[root]=true;
    }
    bool find_(char *str)
    {
        int len=strlen(str);
        int root=0;
        for(int i=0;i<len;i++)
        {
            int id=str[i]-'a';
            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;
    }

    例题·

    1、HUD2072

          题意:统计一篇文章里不同单词出现次数。

          思路:字典树储存,进行多次查找和插入。用flagg判断是否为单词。

          代码:

    #include <iostream>
    #include <cstdio>
    #include <fstream>
    #include <algorithm>
    #include <cmath>
    #include <deque>
    #include <vector>
    #include <queue>
    #include <string>
    #include <cstring>
    #include <map>
    #include <stack>
    #include <set>
    #define ll long long
    #define MOD 998244353 
    #define INF 0x3f3f3f3f
    #define mem(a,x) memset(a,x,sizeof(a))  
    #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    using namespace std;
    const int maxn=2e6+5;
    int tree[maxn][30];   //tree[i][j]表示节点i的第j个儿子的节点编号
    bool flagg[maxn];    //表示以该节点结尾的是一个单词
    int sum[maxn]={0};
    int tot;    //总结点数
    void insert_(char *str,int len)
    {
        int root=0;
        for(int i=0;i<len;i++){
            int id=str[i]-'a';
            if(!tree[root][id])tree[root][id]=++tot;
            root=tree[root][id];
        }
        flagg[root]=true;
    }
    bool find_(char *str,int len)
    {
        int root=0;
        string ans="";
        for(int i=0;i<len;i++)
        {
            int id=str[i]-'a';
            ans+=str[i];
            if(!tree[root][id])return false;
            root=tree[root][id];
        }
        if(flagg[root]==true){
            return true;
        }else{
            return false;
        }
        
    }
    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;
    }
    string s;
    char s1[105];
    int main()
    {
        while(getline(cin,s))
        {
            int ans=0,k=0,d=0;
            if(s[0]=='#')break;
            for(int i=0;i<s.size();i++){
               if(s[i]==' '&&k==1){
                  if(!find_(s1,d)){
                     ans++;
                     insert_(s1,d);
                  }
                  k=0;
                  d=0;
               }else{
                  if(s[i]==' ')continue;
                  s1[d++]=s[i];
                  k=1;
               }
            }
            if(d!=0){
                if(!find_(s1,d)){
                     ans++;
                     insert_(s1,d);
                  }
            }
            cout<<ans<<endl;
            init();
        }
        return 0;
    }

          2、POJ2001

          题意:给你很多单词,问你每个单词的唯一的最短前缀。

          思路:我们先构建好Trie树,然后对每个单词进行find,递归到直到节点出现次数为1,表示这个节点只有这一个单词走过,返

                     回就ok。

          代码:

    #include <iostream>
    #include <cstdio>
    #include <fstream>
    #include <algorithm>
    #include <cmath>
    #include <deque>
    #include <vector>
    #include <queue>
    #include <string>
    #include <cstring>
    #include <map>
    #include <stack>
    #include <set>
    #define ll long long
    #define MOD 998244353 
    #define INF 0x3f3f3f3f
    #define mem(a,x) memset(a,x,sizeof(a))  
    #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    using namespace std;
    const int maxn=2e6+5;
    int tree[maxn][30];   //tree[i][j]表示节点i的第j个儿子的节点编号
    bool flagg[maxn];    //表示以该节点结尾的是一个单词
    int sum[maxn]={0};
    int tot;    //总结点数
    void insert_(char *str)
    {
        int len=strlen(str);
        int root=0;
        for(int i=0;i<len;i++){
            int id=str[i]-'a';
            if(!tree[root][id])tree[root][id]=++tot;
            sum[tree[root][id]]++;
            root=tree[root][id];
        }
        flagg[root]=true;
    }
    string find_(char *str)
    {
        int len=strlen(str);
        int root=0;
        string ans="";
        for(int i=0;i<len;i++)
        {
            int id=str[i]-'a';
            ans+=str[i];
            if(sum[tree[root][id]]<=1)return ans;
            root=tree[root][id];
        }
        return ans;
    }
    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;
    }
    char s[1005][25];
    int main()
    {
        int num=0;
        while(~scanf("%s",s[num])){
            insert_(s[num]);
            num++;
        }
        for(int i=0;i<num;i++)
        {
            printf("%s %s
    ",s[i],find_(s[i]).c_str());
        }
        return 0;
    }

       

    越自律,越自由
  • 相关阅读:
    【web charting】21个Javascript图表插件程序
    【IOC框架】分析与理解
    【待续】【HTML5】用Canvas标签创建第一张条线图
    【转】大型网站后台架构的演变
    初探Visual C# SQL CLR Database Project
    Js中 关于top、clientTop、scrollTop、offsetTop
    JS的正则表达式
    jquery的extend和fn.extend
    C/C++版数据结构之链表<三>
    C/C++ 一点笔记(2)
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/13435565.html
Copyright © 2011-2022 走看看