ai2804词典(Monday)

 

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");
	}
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值