题意:
给你多条英语对应火星文,然后在下面输入一堆火星文,要你翻译成英文,如果一些火星文没有对应的英文的话就输出原火星文就可以了,有就输出英文。
题解:
一看到这道题就想到了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;
}