POJ 2503 Babelfish

题目大意:

        你刚刚从滑铁卢来到了一个大城市,这个大城市中的人操着一种令人费解的方言,幸好你手中有一本字典可以帮你翻译方言。

        现只有一个测例,输入最多有100,000条字典条目,每个条目有两个词,第一个是英语词,后面一个是对应的方言词,中间由一个空格隔开,词典条目结束后会有一空行,接下来会输入最多100,000个方言单词(每个单词一行), 而你的任务是将每一个方言单词翻译成相应的英语单词,如果该方言单词在字典中未出现则输出"eh"。

题目链接

Trie:

注释代码:

/*      
 * Problem ID : POJ 2503 Babelfish
 * Author     : Lirx.t.Una      
 * Language   : G++     
 * Run Time   : 188 ms      
 * Run Memory : 14416 KB      
*/ 

#pragma G++ optimize("O2")

#include <string.h>
#include <stdio.h>

#define	ALPHN		26

#define	TRUE		1
#define	FALSE		0

#define	MAXWDLEN	11
//maximum format string length
//格式字符串的最大长度
//用于同时接受一行英语和外星语
#define	MAXFMTLEN	30

#define	MAXWDN		100001
#define	MAXSTATN	120000

typedef	int		BOOL;

typedef	struct {//trie树结点,即表示状态

	int		out[ALPHN];
	//外星语对应的标号
	//可通过该标号获得外星语所对应的英语
	int		num;
	BOOL	end;//单词结束符,表示该状态是否是一个单词的结束
} Node;

//human language
//存放人话
//h[i]表示第i号人话
char	h[MAXWDN][MAXWDLEN];
char	a[MAXWDLEN];//alien language,存放外星语单词

char	fmt[MAXFMTLEN];//format string,格式字符串
Node	stat[MAXSTATN];

int		tsn;

void
insert( char *w, int num ) {

	int		s;
	int		alph;

	s = 0;
	while ( *w ) {
	
		alph = *(w++) - 'a';

		if ( !stat[s].out[alph] ) {

			stat[s].out[alph] = tsn;
			s = tsn++;

			continue;
		}

		s = stat[s].out[alph];
	}

	stat[s].num = num;//记录该外星单词对应的人话标号
	stat[s].end = TRUE;//标记结尾
}

int
query(char *w) {//字典树查询
	//在trie树上查询单词w的标号

	int		s;
	int		alph;

	s = 0;
	while ( *w ) {
	
		alph = *(w++) - 'a';

		if ( !stat[s].out[alph] )
			return 0;//查询失败直接返回

		s = stat[s].out[alph];
	}

	if ( !stat[s].end )//查询到了单词w,但是trie树中没有以w结尾的单词
		return 0;//同样失败返回

	return stat[s].num;//成功返回对应的人话的标号
}

int
main() {

	int		num;//人话的编号

	num = 1;
	tsn	= 1;
	while ( gets(fmt), *fmt ) {
	
		sscanf(fmt, "%s %s", h[num], a);//解析人话和外星语
		insert( a, num++ );
	}

	while ( ~scanf("%s", a) )
		if ( num = query(a) )
			puts( h[num] );
		else
			puts("eh");//表示没有对应的人话

	return 0;
}

无注释代码:

#pragma G++ optimize("O2")

#include <string.h>
#include <stdio.h>

#define	ALPHN		26

#define	TRUE		1
#define	FALSE		0

#define	MAXWDLEN	11
#define	MAXFMTLEN	30

#define	MAXWDN		100001
#define	MAXSTATN	120000

typedef	int		BOOL;

typedef	struct {

	int		out[ALPHN];
	int		num;
	BOOL	end;
} Node;

char	h[MAXWDN][MAXWDLEN];
char	a[MAXWDLEN];

char	fmt[MAXFMTLEN];
Node	stat[MAXSTATN];

int		tsn;

void
insert( char *w, int num ) {

	int		s;
	int		alph;

	s = 0;
	while ( *w ) {
	
		alph = *(w++) - 'a';

		if ( !stat[s].out[alph] ) {

			stat[s].out[alph] = tsn;
			s = tsn++;

			continue;
		}

		s = stat[s].out[alph];
	}

	stat[s].num = num;
	stat[s].end = TRUE;
}

int
query(char *w) {

	int		s;
	int		alph;

	s = 0;
	while ( *w ) {
	
		alph = *(w++) - 'a';

		if ( !stat[s].out[alph] )
			return 0;

		s = stat[s].out[alph];
	}

	if ( !stat[s].end )
		return 0;

	return stat[s].num;
}

int
main() {

	int		num;

	num = 1;
	tsn	= 1;
	while ( gets(fmt), *fmt ) {
	
		sscanf(fmt, "%s %s", h[num], a);
		insert( a, num++ );
	}

	while ( ~scanf("%s", a) )
		if ( num = query(a) )
			puts( h[num] );
		else
			puts("eh");

	return 0;
}

字符串Hash:

注释代码:

/*       
 * Problem ID : POJ 2503 Babelfish 
 * Author     : Lirx.t.Una       
 * Language   : GCC     
 * Run Time   : 375 ms       
 * Run Memory : 6532 KB       
*/

#pragma GCC optimzie("O2")

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

//hash表的模长
#define	MOD			100003

#define	MAXWDN		100000
#define	MAXWDLEN	11
#define	FMTLEN		30

struct	BNode;

typedef	struct BNode	Node;
typedef	struct BNode *	PtNode;

struct 	BNode {//使用头插法将结点插入hash表

	int			num;//外星语对应的英语的编号
	PtNode		nxt;//使用链式hash,表示结点的next指针
	char		a[MAXWDLEN];//alien language
};

PtNode		hash[MOD];

char		h[MAXWDN][MAXWDLEN];
char		a[MAXWDLEN];
char		fmt[FMTLEN];

int
ELFhash(char *s) {

	unsigned long 	h, g;

	h = 0L;
	while ( *s ) {

		h = ( h << 4L ) + *(s++);
		g = h & 0xf0000000L;
		if ( g )
			h ^= g >> 24L;
		h &= ~g;
	}

	return h % MOD;
}

void
insert( char *w, int num ) {//头插法

	int		key;
	PtNode	node;

	key  = ELFhash(w);//获得hash值
	node = (PtNode)malloc( sizeof(Node) );

	strcpy(node->a, w);//拷贝单词本身于hash结点
	node->num = num;
	//头插法,和图论中邻接表的插入方法一样
	node->nxt = hash[key];
	hash[key] = node;
}

int
query(char *w) {//在hash表中查询指定单词

	int		key;
	PtNode	node;

	key  = ELFhash(w);//获得hash值
	node = hash[key];//获得该hash值所在链表的表头

	while ( node ) {//遍历,直到查到为止
	
		if ( !strcmp(w, node->a) )
			return node->num;

		node = node->nxt;
	}

	return 0;//没找到
}

int
main() {

	int		n;

	n = 0;
	while ( gets(fmt), *fmt ) {
	
		sscanf(fmt, "%s %s", h[++n], a);
		insert( a, n );
	}

	while ( ~scanf("%s", a) )
		if ( n = query(a) )
			puts( h[n] );
		else
			puts("eh");

	return 0;
}

无注释代码:

#pragma GCC optimzie("O2")

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define	MOD			100003

#define	MAXWDN		100000
#define	MAXWDLEN	11
#define	FMTLEN		30

struct	BNode;

typedef	struct BNode	Node;
typedef	struct BNode *	PtNode;

struct 	BNode {

	int			num;
	PtNode		nxt;
	char		a[MAXWDLEN];
};

PtNode		hash[MOD];

char		h[MAXWDN][MAXWDLEN];
char		a[MAXWDLEN];
char		fmt[FMTLEN];

int
ELFhash(char *s) {

	unsigned long 	h, g;

	h = 0;
	while ( *s ) {

		h = ( h << 4 ) + *(s++);
		g = h & 0xf0000000L;
		if ( g )
			h ^= g >> 24;
		h &= ~g;
	}

	return h % MOD;
}

void
insert( char *w, int num ) {

	int		key;
	PtNode	node;

	key  = ELFhash(w);
	node = (PtNode)malloc( sizeof(Node) );

	strcpy(node->a, w);
	node->num = num;
	node->nxt = hash[key];
	hash[key] = node;
}

int
query(char *w) {

	int		key;
	PtNode	node;

	key  = ELFhash(w);
	node = hash[key];

	while ( node ) {
	
		if ( !strcmp(w, node->a) )
			return node->num;

		node = node->nxt;
	}

	return 0;
}

int
main() {

	int		n;

	n = 0;
	while ( gets(fmt), *fmt ) {
	
		sscanf(fmt, "%s %s", h[++n], a);
		insert( a, n );
	}

	while ( ~scanf("%s", a) )
		if ( n = query(a) )
			puts( h[n] );
		else
			puts("eh");

	return 0;
}

单词解释:

babel:n, 巴别塔

babelfish:n, 通天鱼,互通天神和凡间的语言

dialect:n, 方言

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值