zoukankan      html  css  js  c++  java
  • Trie树

    就是把字符串转变成一个树,每个节点连接下一个字符,用空间换时间。

    对于区分大小写或不区分的题目,只需要改变ch[][26]的值就行了。

    ch[u][x]表示u节点(标号决定)下一个x字符节点的标号。

    如果题目让记录附加值,那就用val[标号]在插入时记录一下就好了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=2333;
    struct trie{
        ll ch[maxn][26],siz,val[maxn];
        trie(){
            siz=1;//一开始的时候只有根节点这一个节点 
            memset(ch[0],0,sizeof(ch[0]));
            memset(val,0,sizeof(val));
        }
        inline ll idx(char c){return c-'a';}
        void insert(char *s,ll v)
        {
            ll u=0,len=strlen(s+1);
            for(ll i=1;i<=len;i++){
                ll c=idx(s[i]);
                if(!ch[u][c]){
                    memset(ch[siz],0,sizeof ch[siz]);
                    val[siz]=0;
                    ch[u][c]=siz++;
                } 
                u=ch[u][c];
            }
            val[u]=v;
        }
        ll query(char *s)
        {
            ll u=0,len=strlen(s+1);
            for(ll i=1;i<=len;i++){
                ll c=idx(s[i]);
                if(!ch[u][c])return -1;
                u=ch[u][c];
            }
            return val[u];
        }
    }tr;
    int main()
    {
        return 0;
    }

    P2580 于是他错误的点名开始了

    (名字好奇怪)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=10005*50;
    int n;
    struct trie
    {
        int cnt,ch[maxn][26];
        int vis[maxn];
        trie()
        {
            cnt=1;
            memset(ch[0],0,sizeof ch[0]);
            memset(vis,0,sizeof vis);
        }
        inline int ex(char c){return c-'a';}
        inline void insert(char *s)
        {
            int u=0,len=strlen(s+1);
            for(int i=1;i<=len;i++)
            {
                int c=ex(s[i]);
                if(!ch[u][c]){
                    memset(ch[cnt],0,sizeof ch[cnt]);
                    ch[u][c]=cnt++;
                }
                u=ch[u][c];
            }
        }
        inline int query(char *s)
        {
            int u=0,len=strlen(s+1);
            for(int i=1;i<=len;i++)
            {
                int c=ex(s[i]);
                if(!ch[u][c])return 2;
                u=ch[u][c];
            }
            if(!vis[u]){
                vis[u]++;return 1;
            }
            return 3;
        }
    }tr;
    int main()
    {
        scanf("%d",&n);
        char a[100];
        for(int i=1;i<=n;i++)
        {
            scanf("%s",a+1);
            tr.insert(a);
        }
        int m;
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%s",a+1);
            switch(tr.query(a))
            {
                case(1):{
                    printf("OK
    ");
                    break;
                } 
                case(2):{
                    printf("WRONG
    ");
                    break;
                }
                case(3):{
                    printf("REPEAT
    ");
                    break;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    知识点拾遗——装饰器
    知识点拾遗——函数部分
    re模块和分组
    re模块进阶
    面向对象总结
    模块总结整理
    项目目录结构
    日志(模块logging)
    位、字节、字符 概念
    socketserver实现并发通讯
  • 原文地址:https://www.cnblogs.com/BrotherHood/p/13149633.html
Copyright © 2011-2022 走看看