hdu1251 统计难题 字典树插入,查询模板和空间释放

Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).

Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.

注意:本题只有一组测试数据,处理到文件结束.

Output
对于每个提问,给出以该字符串为前缀的单词的数量.

Sample Input
   
   
   
   
banana band bee absolute acm ba b band abc

Sample Output
   
   
   
   
2 3 1 0

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
using namespace std;
struct trienode
{
    int ncount;//该节点前缀 出现的次数
    struct trienode *next[26+5];//该节点的后续节点
};
void inserttrie(struct trienode* &t,char* str)
{
    struct trienode* temp=t;
    for(int i=0;i<=strlen(str)-1;i++)
    {
        int k=str[i]-'a';
        if(temp->next[k])
            temp->next[k]->ncount++;
        else
        {
            temp->next[k]=(struct trienode *)malloc(sizeof(struct trienode));
            temp->next[k]->ncount=1;
            for(int j=0;j<=25;j++)
                temp->next[k]->next[j]=NULL;
        }
        temp=temp->next[k];
    }
}
int searchtrie(struct trienode *t,char* str)
{
    if(t==NULL)
        return 0;
    struct trienode *temp=t;
    for(int i=0;i<=strlen(str)-1;i++)
    {
        int k=str[i]-'a';//当前字符 应该插入的位置
        if(temp->next[k])
            temp=temp->next[k];
        else
            return 0;
    }
    return temp->ncount;
}
int main()
{
    char str[20];
    struct trienode *root=(struct trienode *)malloc(sizeof(struct trienode));
    root->ncount=1;
    for(int i=0;i<=25;i++)
        root->next[i]=NULL;//初始化根节点。nCount计数为1, next都为null
    while(gets(str))
    {
        if(!strlen(str))
            break;
        inserttrie(root,str);//插入str字符串到root指向的字典树
    }
    while(gets(str))
        cout<<searchtrie(root,str)<<endl;//与字符串最大前缀相同的字符串的个数
    return 0;
}


字典树插入,查询模板和空间释放

#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
struct trienode
{
    int ncount;//该节点前缀 出现的次数
    struct trienode *next[26+5];//该节点的后续节点
};
void inserttrie(struct trienode* &t,string str)
{
    struct trienode* temp=t;
    for(int i=0;i<=str.length()-1;i++)
    {
        int k=str[i]-'a';
        if(temp->next[k])
            temp->next[k]->ncount++;
        else
        {
            temp->next[k]=(struct trienode *)malloc(sizeof(struct trienode));
            temp->next[k]->ncount=1;
            for(int j=0;j<=25;j++)
                temp->next[k]->next[j]=NULL;
        }
        temp=temp->next[k];
    }
}
int searchtrie(struct trienode *t,string str)
{
    if(t==NULL)
        return 0;
    struct trienode *temp=t;
    for(int i=0;i<=str.length()-1;i++)
    {
        int k=str[i]-'a';//当前字符 应该插入的位置
        if(temp->next[k])
            temp=temp->next[k];
        else
            return temp->ncount;
    }
    return temp->ncount;
}
void freetrie(struct trienode* &t)//将字典树t空间释放
{
    if(t==NULL)
        return ;
    for(int i=0;i<=25;i++)
        if(t->next[i])
            freetrie(t->next[i]);
    free(t);
}
int main()
{
    string str="asdfsd";
    struct trienode *root=(struct trienode *)malloc(sizeof(struct trienode));
    root->ncount=1;
    for(int i=0;i<=25;i++)
        root->next[i]=NULL;//初始化根节点。nCount计数为1, next都为null
    inserttrie(root,str);//插入str字符串到root指向的字典树
    cout<<searchtrie(root,"asd")<<endl;//与字符串最大前缀相同的字符串的个数
    freetrie(root);
    return 0;
}


Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let’s say the phone catalogue listed these numbers:
1. Emergency 911
2. Alice 97 625 999
3. Bob 91 12 54 26
In this case, it’s not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob’s phone number. So this list would not be consistent.

Input
The first line of input gives a single integer, 1 <= t <= 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 <= n <= 10000. Then follows n lines with one unique phone number on each line. A phone number is a sequence of at most ten digits.

Output
For each test case, output “YES” if the list is consistent, or “NO” otherwise.

Sample Input
   
   
   
   
2 3 911 97625999 91125426 5 113 12340 123440 12345 98346

Sample Output
   
   
   
   
NO YES


思路:字符串按照字符串大小由大到小进行操作,如果字符串不需要插入操作,则为NO

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
struct node
{
    string s;
    int len;
}str[10010];//目的是让字符串按照字符串大小由大到小进行操作
bool cmp(struct node a,struct node b)
{
    return a.len>b.len;
}
struct trienode
{
    int ncount;//该节点前缀 出现的次数
    struct trienode *next[10+5];//该节点的后续节点
};
bool inserttrie(struct trienode* &t,string str)
{
    bool flag=0;
    struct trienode* temp=t;
    for(int i=0;i<=str.length()-1;i++)
    {
        int k=str[i]-'0';
        if(temp->next[k])
            temp->next[k]->ncount++;
        else
        {
            temp->next[k]=(struct trienode *)malloc(sizeof(struct trienode));
            temp->next[k]->ncount=1;
            for(int j=0;j<=9;j++)
                temp->next[k]->next[j]=NULL;
            flag=1;
        }
        temp=temp->next[k];
    }
    return flag;
}
void freetrie(struct trienode* &t)//将字典树t空间释放
{
    if(t==NULL)
        return ;
    for(int i=0;i<=9;i++)
        if(t->next[i])
            freetrie(t->next[i]);
    free(t);
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        for(int i=0;i<=n-1;i++)
        {
            cin>>str[i].s;
            str[i].len=str[i].s.length();
        }
        sort(str,str+n,cmp);
    struct trienode *root=(struct trienode *)malloc(sizeof(struct trienode));
    root->ncount=1;
    for(int i=0;i<=9;i++)
        root->next[i]=NULL;
    bool f=0;
    for(int k=0;k<=n-1;k++)
    {
    //    cout<<str[k].s<<endl;
        if(!inserttrie(root,str[k].s))
        {
            cout<<"NO"<<endl;
            f=1;
            break;
        }
    }
        if(!f)
            cout<<"YES"<<endl;
        freetrie(root);
    }
    return 0;
}






你可能感兴趣的:(字典树)