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;
    }

       

    越自律,越自由
  • 相关阅读:
    sp2010 升级sp2013 用户无法打开网站
    powerviot install in sharepoint 2013
    can not connect cube in performancce dashboard
    westrac server security configure user info
    添加报表服务在多服务器场
    sharepoint 2013 office web app 2013 文档在线浏览 IE11 浏览器不兼容解决方法
    delete job definition
    目前付款申请单内网打开慢的问题
    item style edit in sharepoint 2013
    Could not load file or assembly '$SharePoint.Project.AssemblyFullName$'
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/13435565.html
Copyright © 2011-2022 走看看