POJ 2503 Babelfish (神族文字)

本文介绍了一个关于语言翻译的编程挑战,通过构建字典来实现外语到英语的转换,利用二分搜索提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                                Babelfish

Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 47332 Accepted: 19828

Description

You have just moved from Waterloo to a big city. The people here speak an incomprehensible dialect of a foreign language. Fortunately, you have a dictionary to help you understand them.

Input

Input consists of up to 100,000 dictionary entries, followed by a blank line, followed by a message of up to 100,000 words. Each dictionary entry is a line containing an English word, followed by a space and a foreign language word. No foreign word appears more than once in the dictionary. The message is a sequence of words in the foreign language, one word on each line. Each word in the input is a sequence of at most 10 lowercase letters.

Output

Output is the message translated to English, one word per line. Foreign words not in the dictionary should be translated as "eh".

Sample Input

dog ogday
cat atcay
pig igpay
froot ootfray
loops oopslay

atcay
ittenkay
oopslay

Sample Output

cat
eh
loops

Hint

Huge input and output,scanf and printf are recommended.

题意概括: 输入多行字符串, 每行字符串由两部分组成,第一部分是一个英文单词,第二部分是一个打乱的字符串。 输入多行字符串后,输入一个空行标识输入结束。然后再输入多个新字符串, 若与打乱的字符串相同,则输出相对应的英文单词;如果不存在相对应的英文单词,则输出eh。


解题思路: 先将第二部分的字符串按照字典序升序排列,然后将每一个新字符串用二分搜索与打乱的字符串进行对比,若比对成功,则输出相对应的英文单词。否则输出eh。


AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

struct node
{
	char a[15];
	char b[15];
}p[100005];

int cmp(node m, node n)
{
	return strcmp(m.b, n.b) < 0; //结构体排序
}

int main(void)
{
	int len = 0, bot, top, mid, flag;
	char str[30], ch[30];
	while(gets(str) != NULL)
	{
		if(str[0] == '\0')
		{
			break;
		}
		sscanf(str, "%s%s", p[len].a, p[len].b);
		len ++;
	}
	
	sort(p, p + len, cmp);
	while(gets(ch) != NULL)
	{
		bot = 0;
		top = len - 1;
		flag = 0;
		while(bot <= top)
		{
			mid = (bot + top) / 2;
			
			if(strcmp(p[mid].b, ch) == 0)
			{
				printf("%s\n", p[mid].a);
				flag = 1;
				break;
			}
			else if(strcmp(p[mid].b, ch) > 0)
			{
				top = mid - 1;
			}
			else
			{
				bot = mid + 1;
			}
		}
		if(flag == 0)
		{
			printf("eh\n");
		}
	}
	return 0;
}

错误原因:此题错了n次。

1. 主要是超时,搜索的时候应该使用二分搜索,节省时间。

2. 忽略了sscanf的功能,是可以将原来的字符串切割成不同的字符串或整型,赋给新的变量。

3. 结构体排序时,要将带排序的变量进行排序,而不是对别的什么进行排序。同时,如果前大后小则为降序排列,如果前小后打则为升序排列。

4. 判断一个字符串是不是回车时,只需要判断这个字符串的第一个字符是不是回车:str[0] =='\0';


经验总结:

1. 当需要将一个字符串进行分时,可以使用sscanf函数, 比如:sscanf(str, "%s%s",  a, b); 这样字符串将会从空格处将字符串进行分割,并且将分割后的字符串分别赋给a和b。

2. 当输入多行字符串并且要对多行字符串按照字典序进行排序时,可以将字符串设置为结构体,然后用另一个字符串作为这个结构体的变量。比如:

struct node
{
	char a[15];
	char b[15];
}p[100005];


第二次使用比较交换排序时没有AC(超时了)的代码:

#include<stdio.h>
#include<string.h> 
#include<algorithm>
using namespace std;

struct note
{
	char a[30];
	char b[30];
}q[100005];


int main(void)
{
	
	char c[30], str[30], ch[30];
	int len = 1, i, j, left, right, mid, flag;
	while(gets(str) != NULL)
	{
		if(str[0] == '\0')
		{
			break;
		}
		sscanf(str, "%s%s", q[len].a, q[len].b);
		len ++;
	}
	
	for(i = 1; i <= len - 2; i ++)
	{
		for(j = i + 1; j <= len - 1; j ++)
		{
			if(strcmp(q[i].b, q[j].b) > 0)
			{
				strcpy(c, q[i].b);
				strcpy(q[i].b, q[j].b);
				strcpy(q[j].b, c);
				strcpy(c, q[i].a);         //错误点(忽略了要将a字符串单独进行排序) 
				strcpy(q[i].a, q[j].a);   // 
				strcpy(q[j].a, c);		 //	
			}
		}
	}

	
	while(gets(ch) != NULL)
	{
		left = 1;
		flag = 0;
		right = len - 1;
		while(left <= right)
		{
			mid = (left + right) / 2;
			if(strcmp(ch, q[mid].b) == 0)
			{
				printf("%s\n", q[mid].a);
				flag = 1;
				break;
			}
			else if(strcmp(ch, q[mid].b) < 0)
			{
				right = mid - 1;
			}
			else
			{
				left = mid + 1;
			} 
		}
		if(flag == 0)
		{
			printf("eh\n");
		}
	}
	return 0;
} 



错误了一回:原因是将比较交换排序与sort排序混为一坛:
                    sort排序时是以某一个标准对整个字符串进行排序;
                    比较交换排序是单独对每一部分进行排序,需要将带排序的每一部分字符串分别进行排序。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值