zoukankan      html  css  js  c++  java
  • tire 树入门

    博客:

    模板:

    前缀是否出现:

    /*
      trie tree的储存方式:将字母储存在边上,边的节点连接与它相连的字母 
      trie[rt][x]=tot:rt是上个节点编号,x是字母,tot是下个节点编号 
    */ 
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define maxn 2000010
    using namespace std;
    int tot=1,n;
    int trie[maxn][26];
    //bool isw[maxn];查询整个单词用
    void insert(char *s,int rt)
    {
        for(int i=0;s[i];i++)
        {
            int x=s[i]-'a';
            if(trie[rt][x]==0)//现在插入的字母在之前同一节点处未出现过 
            {
                trie[rt][x]=++tot;//字母插入一个新的位置,否则不做处理 
            }
            rt=trie[rt][x];//为下个字母的插入做准备  
        }
        /*isw[rt]=true;标志该单词末位字母的尾结点,在查询整个单词时用到*/
    }
    bool find(char *s,int rt)
    {
        for(int i=0;s[i];i++)
        {
            int x=s[i]-'a';
            if(trie[rt][x]==0)return false;//以rt为头结点的x字母不存在,返回0 
            rt=trie[rt][x];//为查询下个字母做准备 
        }
        return true;
        //查询整个单词时,应该return isw[rt] 
    }
    char s[22];
    int main()
    {
        tot=0;
        int rt=1;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            cin>>s;
            insert(s,rt);
        }
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            cin>>s;
            if(find(s,rt))printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    
    数组模拟
    View Code

    前缀出现的次数:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int trie[400001][26],len,root,tot,sum[400001];
    bool p;
    int n,m; 
    char s[11];
    void insert()
    {
        len=strlen(s);
        root=0;
        for(int i=0;i<len;i++)
        {
            int id=s[i]-'a';
            if(!trie[root][id]) trie[root][id]=++tot;
            sum[trie[root][id]]++;//前缀后移一个位置保存 
            root=trie[root][id];
        }
    }
    int search()
    {
        root=0;
        len=strlen(s);
        for(int i=0;i<len;i++)
        {
            int id=s[i]-'a';
            if(!trie[root][id]) return 0;
            root=trie[root][id];
        }//root经过此循环后变成前缀最后一个字母所在位置的后一个位置 
        return sum[root];//因为前缀后移了一个保存,所以此时的sum[root]就是要求的前缀出现的次数 
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            cin>>s;
            insert();
        }
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            cin>>s;
            printf("%d
    ",search());
        }
    }
    
    数组模拟
    View Code

    模板题:hdu 1252

    前缀出现的次数:

    #include<stdio.h>
    #include<algorithm>
    #include<iostream>
    #include<string.h>
    #include<string>
    using namespace std;
    const int max_=1e6+5;
    int trie[max_][26];
    int tot=0;
    char s[max_];
    int sum[max_];
    void insert(char str[])
    {
        //int len=str.size();
        int rt=0;
        for(int i=0;str[i];i++)
        {
            int k=str[i]-'a';
            if(!trie[rt][k])
                trie[rt][k]=++tot;
                sum[trie[rt][k]]++;
            rt=trie[rt][k];
        }
    }
    int find(char str[])
    {
        //int len=strlen(str);
        int rt=0;
        for(int i=0;str[i];i++)
        {
            int k=str[i]-'a';
            if(!trie[rt][k])
                return 0;
            rt=trie[rt][k];
        }
        return sum[rt];
    }
    int main()
    {
        /*std::ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);*/
        //string str;
        while(gets(s))
        {
            //cout<<str<<endl;
            if(s[0]=='')
                break;
            insert(s);
        }
        while(scanf("%s",s)!=EOF)
        {
           // printf("ok
    ");
            int ant=find(s);
            printf("%d
    ",ant);
        }
    }
    View Code

    一句话有多少个单词:hdu 2072

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<string.h>
    #include<sstream>
    using namespace std;
    const int max_=2e4+5;
    int tot;
    int trie[max_][26];
    bool book[max_];
    void insert(string str)
    {
        int len=str.size();
        int rt=0;
        for(int i=0;i<len;i++)
        {
            int k=str[i]-'a';
            if(!trie[rt][k])
                trie[rt][k]=++tot;
            rt=trie[rt][k];
        }
        book[rt]=1;
    }
    bool find_(string str)
    {
        int len=str.size();
        int rt=0;
        for(int i=0;i<len;i++)
        {
            int k=str[i]-'a';
            if(!trie[rt][k])
                return 0;
            rt=trie[rt][k];
        }
       if(book[rt])
        return 1;
       else
        return 0;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        string str1,str2;
        while(getline(cin,str1))
        {
            if(str1=="#")
                break;
            tot=0;
            int ant=0;
            memset(trie,0,sizeof(trie));
            memset(book,0,sizeof(book));
            stringstream ss(str1);
            while(ss>>str2)
            {
                //cout<<ss<<endl;
                if(!find_(str2))
                {
                    ant++;
                    insert(str2);
                }
            }
            printf("%d
    ",ant);
        }
    }
    View Code
  • 相关阅读:
    nginx 特定目录禁止php执行
    linux awk命令详解
    漫谈大型网站架构
    ThinkPHP 自动验证实例
    使用jquery时一些小技巧的总结
    fputcsv 导出CSV、Excel DownLoad
    文件操作总结
    rc.local 开机自启脚本无法启动
    Windows pycharm Terminal使用Anaconda 的Prompt
    解决hash冲突方法
  • 原文地址:https://www.cnblogs.com/linhaitai/p/9942755.html
Copyright © 2011-2022 走看看