HDU1075 不错的字典树题

题意:
给你多条英语对应火星文,然后在下面输入一堆火星文,要你翻译成英文,如果一些火星文没有对应的英文的话就输出原火星文就可以了,有就输出英文。
题解:
一看到这道题就想到了map容器,奈何挺久没用过了,导致我很难下手,还是去看了别人怎么写的记忆才慢慢复苏,怎么说呢,STL是个神器,但是我用不习惯。。。ORZ,既然这道题是一道字典树的题目的话,咱们就用字典树的做法去做吧。
怎么做呢?把输入的英文存放起来,而火星文则存进字典树中,在每个火星文最后的树节点中标记编号,然后find函数查找这个火星文是否有对应的英文,有的话就输出英文,没有就输出原文。这道题就过了,但是有点坑爹的是,要稍微判断一下没有火星文的情况,另外还有一点坑爹的就是你数组要开到100万,不然会超时的,这一度让我怀疑是不是我字典树写错了。
还有一种省略了数组的写法,在我自己的做法的下面,大家可以去看看。

字典树做法:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN=1000000+7;//这坑爹的玩意要开100W..我开3000超时导致我一度以为我的字典树写错了。 
struct node
{
    int cnt;
    node *next[26];
    node(){
        cnt=-1;//这里不能赋值为0,因为有可能有一些火星文没对应的英语,却因为返回的不是-1而输出了s[0].导致了出错。 
        for(int i=0;i<26;i++)
        next[i]=0;
    }
}*root;
int tot=0;
char s[MAXN][15];
void insert(char *s)
{
    node *r=root;
    for(int i=0;s[i];i++)
    {
        int x=s[i]-'a';
        if(r->next[x]==0) r->next[x]=new(node);
        r=r->next[x];
    }
    r->cnt=tot++;
}
int find(char *s)
{
    node *r=root;
    for(int i=0;s[i];i++)
    {
        int x=s[i]-'a';
        if(r->next[x]==0) return -1;
        r=r->next[x];
    }
    return r->cnt;
}
int main()
{
    root=new(node);
    char c[3007];
    scanf("%s",c);
    int k=0;
    while(~scanf("%s",s[k]))
    {
        if(strcmp(s[k],"END")==0)
        break;
        k++;
        scanf("%s",c);
        insert(c);
    }
    scanf("%s",c);
    getchar();
    while(gets(c))
    {
        if(strcmp(c,"END")==0)
        break;
        char x[15];
        int m=0;
        int len=strlen(c);
        for(int i=0;i<len;i++)
        if(isalpha(c[i]))
        x[m++]=c[i];
        else
        {
            if(m==0)//特判一下没有字母就输出标点符号之类的。 
            {
                printf("%c",c[i]);
                continue;
            }
            x[m]='\0';
            m=0;
            if(find(x)!=-1)
            printf("%s",s[find(x)]);
            else
            printf("%s",x);
            printf("%c",c[i]);
        }
        printf("\n");
    }
} 

还有一种不用数组更好的写法:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
    int cnt;
    char s[15];
    node *next[26];
    node(){
        cnt=0;
        for(int i=0;i<26;i++)
        next[i]=0;
        s[0]='\0';
    }
}*root;
char c[15];
void insert(char *s)
{
    node *r=root;
    for(int i=0;s[i];i++)
    {
        int x=s[i]-'a';
        if(r->next[x]==0) r->next[x]=new(node);
        r=r->next[x]; 
    }
    r->cnt=1;
    strcpy(r->s,c);
}
char *find(char *s)
{
    node *r=root;
    for(int i=0;s[i];i++)
    {
        int x=s[i]-'a';
        if(r->next[x]==0) return s;
        r=r->next[x];
    }
    if(r->cnt)
    return r->s;
    else
    return s;
} 
void del(node *head)
{
    for(int i=0;i<26;i++)
    if(head->next[i])
    del(head->next[i]);
    delete(head);
}
int main()
{
    root=new(node);
    char s[15];
    scanf("%s",c);
    while(~scanf("%s",c))
    {
        if(strcmp(c,"END")==0)
        break;
        scanf("%s",s);
        insert(s);
    }
    scanf("%s",c);
    getchar();
    char str[3007];
    while(gets(str))
    {
        if(strcmp(str,"END")==0)
        break;
        int len=strlen(str);
        int m=0;
        for(int i=0;i<len;i++)
        if(str[i]>='a'&&str[i]<='z')
        s[m++]=str[i];
        else
        {
            if(m==0)
            printf("%c",str[i]);
            else
            {
                s[m]='\0';//要学会养成自己补上'\0'的习惯。
                printf("%s",find(s));
                printf("%c",str[i]);
                m=0; 
            }
        }
        printf("\n");
    }
    del(root);
}

map容器的写法:

#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
const int MAXN=3000+7;
map<string,string>mp;
char s[MAXN];
int main()
{
    string a,b;
    cin>>a;
    while(cin>>a)
    {
        if(a=="END")
        break;
        cin>>b;
        mp[b]=a;
    }
    cin>>a;
    getchar();//要加上这个吸收换行符。 
    while(1){
        gets(s);
        if(strcmp(s,"END")==0)
        break;
        int len=strlen(s);
        a="";
        for(int i=0;i<len;i++)
        {
            if(isalpha(s[i]))
            a+=s[i];
            else
            {
                if(mp.find(a)!=mp.end())
                cout<<mp[a];
                else
                cout<<a;
                a="";
                cout<<s[i];
            }
        }
        cout<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值