传送门UVa 10282 & POJ 2503 - Babelfish
题意大家肯定都读得懂。
一开始我抱着侥幸的心里,没判重,直接映射了哈希值。。然后UVa就给了我一发WA。
这题的关键是建立单词(oodog)和单词所在二维数组(dic[l])的位置的关系。
和前几题一样,我选择了BKDHash作为哈希函数。其实我觉得从隐式图遍历专题开始就应该归为哈希表的应用。。
在第一阶段,也就是字典的输入阶段,把英文和单词按顺序储存起来,并把位置映射到哈希表上,如果有重复的哈希值,管自己插即可XD。
第二阶段,即查找阶段,把每个单词也映射成哈希表,如果表上有元素存在,就是那个单词。这时候有可能一个元素有多个值,就按照链表比较下来。如果有的话,就返回位置,没有,就是没有了。。。
详情见代码
#include <cstdio>
#include <cstring>
using namespace std;
const int HashSize = 200000;
char eng[110000][30], dic[110000][30];
int head[HashSize], next[HashSize];
int BKDHash(char *c);
int Search(char *s);
void Insert(int s);
int main()
{
//freopen("input.txt", "r", stdin);
int next, i, j, k, l = 1;
bool stopFlag;
char str[20], temp[50];
while (fgets(temp, 50, stdin))
{
if (temp[0] == '\n')
break;
k = 0;
for (i = 0; temp[i] != ' '; i++)
eng[l][i] = temp[i];
eng[l][i] = 0;
for (++i; temp[i] != '\n'; i++)
dic[l][k++] = temp[i];
dic[l][k] = 0;
Insert(l);
l++;
}
while (~scanf("%s", str))
{
int num = Search(str);
if (num == 0)
puts("eh");
else
puts(eng[num]);
}
return 0;
}
int BKDHash(char *c) //哈希函数。
{
int seed = 131;
int Hash = 0;
for (int i = 0; i < strlen(c); i++)
Hash = Hash * seed + c[i];
return (Hash & 0x7FFFFFFF) % HashSize;
}
void Insert(int s)
{
int v = BKDHash(dic[s]);
next[s] = head[v]; //插入到当前值的首部
head[v] = s;
}
int Search(char *s)
{
int v = BKDHash(s);
int u = head[v];
while (u)
{
if (strcmp(s, dic[u]) == 0)
return u;
u = next[u];
}
return 0;
}