Perfect Hash
Perfect Hash |
Perfect Software, Inc. has obtained a government contract to examine text flowing through a high-speed network for the occurrence of certain words. Your boss, Wally Perfect, has designed a parallel processing system which checks each word against a group of small perfect hash tables.
A perfect hash function maps its input directly to a fully occupied table. Your job is to construct the perfect hash functions from the lists of words in each table. The hash function is of the form , where C is a positive integer you are to discover, w is an integer representation of an input word, and n is the length of the table. C must be as small as possible. Note that
is the floor function and that
for some real number R is the largest integer that is
.
Here are Wally's notes on the subject:
Let consist of positive integers
. The problem is to find the smallest positive integer Csuch that
for all
.
C must be a multiple of at least one element of W.
If some
for all
,
then the next largest C that could resolve the conflict is at least
Since all such conflicts must be resolved, it is advantageous to choose the largest candidate from among the conflicts as the next Cto test.
You are to convert each word to a number by processing each letter from left to right. Consider `a' to be 1, `b' to be 2, , `z' to be 26. Use 5 bits for each letter (shift left by 5 or multiply by 32). Thus `a' = 1, `bz' =
.
Input
Input to your program will be a series of word lists, one per line, terminated by the end-of-file. Each line consists of between two and thirteen words of at most five lower case letters each, separated from each other by at least one blank. There will always be at least one one-letter word.
For each list, you are to print the input line. On the next line, print the C for the hash function determined by the list. Print a blank line after each C.
C will always fit in a 32-bit integer.
Sample input
this is a test of some words to try out a bee see dee the of and to a in that is i it with for as
Sample output
this is a test of some words to try out 17247663 a bee see dee 4427 the of and to a in that is i it with for as 667241
这题完全是根据题意来做。。 题目读懂了就好办了。。。
输入一堆的单词 。。每个单词都可以转换成一个数字。。转换的方式为三十二进制。每个字母都用ASCALL码表示。。
然后得到所有字母代表的数字W。。求出其中最小的C。 如果 C满足 for all
,。就要把C进行变化。。
。。。直到不满足位置。。。。
注意:w是有可能为0的。。一开始忘记判断导致RE。。。
代码
#include <stdio.h>
#include <string.h>
char str[505];
int C;
int w[55];
int n;
int min(int a, int b)
{
return a < b ? a : b;
}
void getc()
{
n = 0;
int len = strlen(str);
for (int i = 0; i < len; i ++)
{
if (str[i] == ' ')
{
n ++;
}
else
{
w[n] = w[n] * 32 + (str[i] - 'a' + 1);
}
}
}
int judge()
{
for (int i = 0; i <= n; i ++)
for (int j = i + 1; j <= n; j ++)
{
if (w[i] == 0 || w[j] == 0)
continue;
if ((C / w[i]) % (n + 1) == (C / w[j]) % (n + 1))
{
C = min((C / w[i] + 1) * w[i], (C / w[j] + 1) * w[j]);
return 0;
}
}
return 1;
}
int main()
{
int tt = 1;
while(gets(str) != NULL)
{
memset(w, 0, sizeof(w));
getc();
C = 999999999;
for (int i = 0; i <= n; i ++)
{
if (C > w[i])
C = w[i];
}
while (judge() == 0);
printf("%s\n", str);
printf("%d\n\n", C);
}
return 0;
}