Trie/最短的名字

题目链接

/*
简单trie树的应用,注意在初始化的时候要把cnt也初始化,不然,WA!
下面的四分代码各有特点
*/
//数组型,名字查询。
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000000;
struct tire{
    int wd[27];
    int cnt;
    void init()
    {
        cnt=0;
        memset(wd,0,sizeof(wd));
    }
};
tire tree[maxn];
int tot=1,n,m;
void Insert(char* s,int root)
{
    for(int i=0;s[i];i++)
    {
        int k=s[i]-'a';
        if(!tree[root].wd[k])
        {
            tree[tot].init();
            tree[root].wd[k]=tot++;
        }
        root=tree[root].wd[k];
        tree[root].cnt++;
    }
}
int sum=0;
int query (int root)
{
    int sum=0;
    for(int i=0;i<=25;i++)
    {
        if(tree[root].wd[i])
        {
            int ro=tree[root].wd[i];
            sum+=tree[ro].cnt;
            if(tree[ro].cnt>1)
                sum+=query(ro);
        }
    }
    return sum;
}
char name[1000000+5];
int main ()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int root=0;
        tot=1;
        tree[root].init();
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",name);
            Insert(name, root);
        }
        printf("%d
",query(root));
    }
    return 0;
}
//指针型,DFS查询
#include<cstdio>
#include<cstring>
#include<iostream>
const int maxn=1000000+5;
const int si=26;
int n;
char name[maxn];
struct node
{
    int n;
    node *chi[si];
    void init()
    {
        n=0;
        for(int i=0;i<si;i++)
            chi[i]=NULL;
    }
};
void Insert(char *s,node *root)
{
    for(int i=0;s[i];i++)
    {
        if(root->chi[s[i]-'a']==NULL)
        {
            node *t=(node *)malloc(sizeof(node));
            t->init();
            root->chi[s[i]-'a']=t;
        }
        root=root->chi[s[i]-'a'];
        root->n++;
    }
}
int query(node *root)
{
    int sum=0;
    for(int i=0;i<si;i++)
    {
        if(root->chi[i]!=NULL)
        {
            node *t=root->chi[i];
            sum+=t->n;
            if(t->n>=2)
                sum+=query(t);
        }
    }
    return sum;
}
void rease(node *root)
{
    for(int i=0;i<si;i++)
    {
        if(root->chi[i]!=NULL)
            rease(root->chi[i]);
    }
    delete root;
}
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int n=0;
        scanf("%d",&n);
        node *root=(node *)malloc(sizeof(node));
        root->init();
        for(int i=0;i<n;i++)
        {
            scanf("%s",name);
            Insert(name, root);
        }
        printf("%d
",query(root));
    }
}
//数组型,DFS查询
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000000;
struct tire{
    int wd[27];
    int cnt;
    void init()
    {
        cnt=0;
        memset(wd,0,sizeof(wd));
    }
};
tire tree[maxn];
int tot=1,n,m;
void Insert(char* s,int root)
{
    for(int i=0;s[i];i++)
    {
        int k=s[i]-'a';
        if(!tree[root].wd[k])
        {
            tree[tot].init();
            tree[root].wd[k]=tot++;
        }
        root=tree[root].wd[k];
        tree[root].cnt++;
    }
}
int sum=0;
int query (int root)
{
    int sum=0;
    for(int i=0;i<=25;i++)
    {
        if(tree[root].wd[i])
        {
            int ro=tree[root].wd[i];
            sum+=tree[ro].cnt;
            if(tree[ro].cnt>1)
                sum+=query(ro);
        }
    }
    return sum;
}
char name[1000000+5];
int main ()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int root=0;
        tot=1;
        tree[root].init();
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",name);
            Insert(name, root);
        }
        printf("%d
",query(root));
    }
    return 0;
}
//数组型,名字查询,名字在string中保存,虽然可以节约空间,但是由于string只能用cin输入,所以时间慢。
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
const int maxn=1000000;
struct tire
{
    int wd[27];
    int cnt;
    void init()
    {
        cnt=0;
        memset(wd,0,sizeof(wd));
    }
};
tire tree[maxn];
int tot=1,n,m;
void Insert(string s,int root)
{
    for(int i=0;s[i];i++)
    {
        int k=s[i]-'a';
        if(!tree[root].wd[k])
        {
            tree[tot].init();
            tree[root].wd[k]=tot++;
        }
        root=tree[root].wd[k];
        tree[root].cnt++;
    }
}
int query (string s,int root)
{
    for(int i=0;s[i];i++)
    {
        int k=s[i]-'a';
        root=tree[root].wd[k];
        if(tree[root].cnt==1)
            return i+1;

    }
    return tree[root].cnt+1;
}
string name[1000+5];
int main ()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int root=0;
        tot=1;
        tree[root].init();
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            cin>>name[i];
            Insert( name[i], root);
        }
        int  ans=0;
        for(int i=1;i<=n;i++)
        {
            ans+=query(name[i], root);
        }
        printf("%d
",ans);
    }
    return 0;
}
想的太多,做的太少。
原文地址:https://www.cnblogs.com/pealicx/p/6115597.html