题目大意:
你刚刚从滑铁卢来到了一个大城市,这个大城市中的人操着一种令人费解的方言,幸好你手中有一本字典可以帮你翻译方言。
现只有一个测例,输入最多有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, 方言