2804:词典
时间限制:3000ms
内存限制:65536kB
描述
你旅游到了一个国外的城市。那里的人们说的外国语言你不能理解。不过幸运的是,你有一本词典可以帮助你。
输入
首先输入一个词典,词典中包含不超过100000个词条,每个词条占据一行。每一个词条包括一个英文单词和一个外语单词,两个单词之间用一个空格隔开。而且在词典中不会有某个外语单词出现超过两次。词典之后是一个空行,然后给出一个由外语单词组成的文档,文档不超过100000行,而且每行只包括一个外语单词。输入中出现单词只包括小写字母,而且长度不会超过10。
输出
在输出中,你需要把输入文档翻译成英文,每行输出一个英文单词。如果某个外语单词不在词典中,就把这个单词翻译成“eh”。
样例输入
dog ogday
cat atcay
pig igpay
froot ootfray
loops oopslay
atcay
ittenkay
oopslay
样例输出
cat
eh
loops
提示
输入比较大,推荐使用C语言的I / O函数。
来源
翻译自Waterloo local 2001.09.22的试题
从物院转计院,暑假补课学程序设计Ⅱ,在百练(www.bailian.openjudge.cn)上刷题,把code和bug都记下来吧
已通过版本(time limit exceed):
#include<stdio.h>
#include<string.h>
#include<malloc.h>
struct dict{
char EnWord[11];
char FoWord[11];
};
void split(char *str1,char *str2,char *line){
int i,j=0;
for(i=0;i<22;i++){
if(line[i]==32){
str1[i]=0;
break;
}
str1[i]=line[i];
}
while(i<22){
i++;
str2[j]=line[i];
j++;
if(line[i]=='\0')
break;
}
}
int main(){
char str1[11],str2[11],line[22],f;
struct dict *addr[100000],*fp=NULL;
int i=0,j=0,trans[100000]={0},k=0,back=0;
gets(line);
while(line[0]!='\0'){
split(str1,str2,line);
fp=(struct dict *)malloc(sizeof(struct dict));
strcpy(fp->EnWord,str1);
strcpy(fp->FoWord,str2);
addr[i]=fp;i++;
gets(line);
}
while(scanf("%s",line)!=EOF){
for(j=0;j<i;j++){
if(strcmp(line,addr[j]->FoWord)==0){
printf("%s\n",addr[j]->EnWord);
break;
}
}
if(j==i)printf("eh\n");
k++;
}
}
bug:
1、第一次上机用百练,不知道输出可以一边读一边打印到stdout,用了一个数组存着最后一起打印,不过也没事,应该也可以,就是源代码找不到了,忘了在上机环境多保存几个版本了
2、偶然发现把“eh”打印成“en”了,或许这就是Chingish吧,恩恩恩嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯
3、最重要的一点是数组大小要设成11,用来装字符串的‘\0’,我先设成的10,调了一个下午,改一个数字就好,吐血
4、这一篇代码其实有一个笔误却反而让它过了,int main()函数本来要return 1;的,可能改的时候改掉了吧,我也是后来才发现return 的值大概也要当做输出,运气运气
5、虽然过了,但总是超时,我看了一下其他很多博主的代码,用的是C++中的TSL(STL)中的map结构,代码又短又不超时,好棒棒,可惜我不会C++啊(下周就学),我就用python3的dict类型写了个,因为我记得这个类型用的是hashtable,特别利索,果然accept了,恩,也是又短又快
6、写map版本时发现要设定读到末尾的 终止条件,否则就会有output limit exceed
7、快排
void qsort(void *base, size_t nitems, size_t size, int (*cmp)(const void *, const void*))
中的cmp函数的参数看成和base一样的运用
import sys
dictionary = {}
while True:
line=sys.stdin.readline().replace('\n','')
if(line=='' or line=='\n'):
break
li = line.split(' ')
dictionary[li[1]] = li[0]
while True:
line=sys.stdin.readline().replace('\n','')
if(line=='' or line=='\n'):
break
if(line not in dictionary.keys()):
print("eh")
else:
print("%s"%dictionary[line])
更新:
c++ stl写的 已ac
#include <string>
#include <algorithm>
#include <map>
#include <iostream>
using namespace std;
int main(){
map<string,string> dict;
while(1){
string key,value,line;
string::iterator it;
getline(cin,line);
if(line.empty())break;
value.assign(line,0,line.find(" "));
key.assign(line.begin()+line.find(" ")+1,line.end());
dict[key]=value;
}
string index;
while(cin>>index){
if(dict.find(index)!=dict.end()){
cout<<dict[index]<<endl;
}
else{
cout<<"eh"<<endl;
}
}
}
c写的hash表(散列解决的冲突):time limit exceed
#include<stdio.h>
#include<string.h>
#include<malloc.h>
struct word{
char EnWord[11];
int code;
char FoWord[11];
};
int encode(char line[11]){
int len=strlen(line);
int sum=0;
for(int i=0;i<len;i++){
sum+=(line[i]-'0')*24;
sum%=100000;
}
return sum;
}
word *dict[100001];
int main(){
while(1){
char line[22]={0};
char eng[11]={0},fre[11]={0};
gets(line);
if(line[0]=='\0')break;
sscanf(line,"%s %s",eng,fre);
word *constant=(word *)malloc(sizeof(word));
strcpy(constant->EnWord,eng);
strcpy(constant->FoWord,fre);
constant->code=encode(fre);
if(!dict[constant->code]){
dict[constant->code]=constant;
}
else{
int code=constant->code;
while(dict[code]){code+=1;code%=100000;}
dict[code]=constant;
}
}
char fre[11]={0};
while(gets(fre)){
int code=encode(fre);
while(1){
if(!dict[code]){
printf("eh\n");
break;
}
if(strcmp(dict[code]->FoWord,fre)==0){
printf("%s\n",dict[code]->EnWord);
break;
}
code+=1;
code%=100000;
}
}
}
c的快排加二分查找的思路写的 ac
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct dict{
char EnWord[11];
char FoWord[11];
}*word;
int cmp(const void *a,const void *b){
return strcmp((*(word*)a)->FoWord,(*(word*)b)->FoWord);
}
int main(){
word addr[100000]={NULL};
int i=0,j=0,k=0;
while(1){
char line[22]={0};
gets(line);
if(line[0]=='\0')break;
char str1[11]={0},str2[11]={0};
sscanf(line,"%s%s",str1,str2);
word fp=(word)malloc(sizeof(struct dict));
strcpy(fp->EnWord,str1);
strcpy(fp->FoWord,str2);
addr[i++]=fp;
}
int len=i;
qsort(addr,len,sizeof(word),cmp);
char line[22]={0};
while(gets(line)){
j=0;k=len-1;
while(j<=k){
int b=strcmp(line,addr[(j+k)/2]->FoWord);
if(b>0){
j=(j+k)/2+1;
}
else if(b<0){
k=(j+k)/2-1;
}
else {
break;
}
}
if(j<=k)printf("%s\n",addr[(j+k)/2]->EnWord);
else printf("eh\n");
}
}