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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章