uva 188 Perfect Hash

题目地址:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=124

题目描述:

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 tex2html_wrap_inline63 , 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 tex2html_wrap_inline73 is the floor function and that tex2html_wrap_inline75 for some real number R is the largest integer that is tex2html_wrap_inline79 .

Here are Wally’s notes on the subject:

Let tex2html_wrap_inline81 consist of positive integers tex2html_wrap_inline83 . The problem is to find the smallest positive integer C such that

tex2html_wrap_inline87 for all tex2html_wrap_inline89 .

C must be a multiple of at least one element of W.

If some

tex2html_wrap_inline95 for all tex2html_wrap_inline97 ,

then the next largest C that could resolve the conflict is at least

displaymath61

Since all such conflicts must be resolved, it is advantageous to choose the largest candidate from among the conflicts as the next C to 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, tex2html_wrap_inline103 , z' to be 26. Use 5 bits for each letter (shift left by 5 or multiply by 32). Thusa’ = 1, `bz’ = tex2html_wrap_inline105 .

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

题意:

找出完美hash最小的C值。

题解:

模拟,模拟规则题意已给出。

代码:

#include "stdio.h"
#include "string.h"
#include "ctype.h"
#define MM 2147483647
char letters[20][10];
char in_str[500];
int w[20], cnter[20];
int C = 0, llen = 0, slen = 0, wlen = 0, Cm = 0;
int get_w(char ss[])
{
    int sum = 0;
    int ss_len = strlen(ss);
    for(int i = 0; i <= ss_len - 1; i++)
        sum = sum * 32 + (ss[i] - 'a' + 1);
    return sum;
}
int init()
{
    llen = 0;
    slen = (int)strlen(in_str);
    int k = 0;
    for(int i = 0; i<= slen - 1; i++)
    {
        if(isalpha(in_str[i]))
            letters[llen][k++] = in_str[i];
        else
        {
            if(k > 0)
            {
                letters[llen++][k] = '\0';
                w[llen - 1] = get_w(letters[llen - 1]);
            }
            k = 0;
        }
    }
    if(k > 0)
    {
        letters[llen++][k] = '\0';
        w[llen - 1] = get_w(letters[llen - 1]);
    }
    wlen = llen;
    return 0;
}
int get_max()
{
    int min = MM;
    for(int i = 0; i <= wlen - 1; i++)
        if(min > w[i])
            min = w[i];
    return min;
}
int min_C(int a, int b)
{
    return a < b ? a : b;
}
int find_C()
{
    for(int i = 0; i <= wlen - 1; i++)
        for(int j = i + 1; j <= wlen - 1; j ++)
            if(((C / w[i]) % wlen) == ((C / w[j]) % wlen))
            {
                C = min_C((C/w[i] + 1) * w[i], (C/w[j] + 1) * w[j]);
                return 0;
            }
    Cm = C;
    return 1;
}
int main()
{
    while (fgets(in_str, 500, stdin) != NULL)
    {
        if(in_str[0] == '\n') continue;
        if(in_str[strlen(in_str) - 1] == '\n')
            in_str[strlen(in_str) - 1] = '\0';
        init();
        Cm = MM;
        C = get_max();
        while (Cm == MM)
            find_C();
        printf("%s\n%d\n\n", in_str, Cm);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值