poj 2503(字符串hash)

解题思路(copy别人的):通过ELFhash函数来做。冲突处理则是用到链表的方法。


#include <iostream>
#include <fstream>
#include <string.h>

#define N 100001
#define strSize 15

using namespace std;

struct Hash
{
    bool used;
    char fn[strSize],en[strSize];
    Hash* next;    //用于冲突时构造链表
    Hash(){used=false; next=NULL;}
    Hash(char *f,char *e)
    {
        strcpy(fn,f);
        strcpy(en,e);
        used=false;
        next=NULL;
    }    
}h[N];

int ELFhash(char *key){

    unsigned long h=0;
    unsigned long x=0;

    while(*key)
    {
        h=(h<<4)+(*key++);  //h左移4位,当前字符ASCII存入h的低四位
                if( (x=h & 0xF0000000L)!=0)
        { //如果最高位不为0,则说明字符多余7个,如果不处理,再加第九个字符时,第一个字符会被移出
          //因此要有如下处理
          h^=(x>>24);
          //清空28~31位
          h &=~x;
        }
    }
    return h % N;
}


int main()
{
    freopen("acm.txt","r",stdin);
    char str[30],en[strSize],fn[strSize];
    Hash *p;
    int sign=1,key;

    while(gets(str))
    {
        if(str[0]=='\0')
        {
            sign=0;
            continue;
        }
        if(sign)   //输入字典
        {
            sscanf(str,"%s %s",&en,&fn);
            key=ELFhash(fn);    //获取hash值
            if(!h[key].used)    //对应到hash表中
            {
                h[key].used=true;
                strcpy(h[key].en,en);
                strcpy(h[key].fn,fn);
            }
            else   //处理冲突
            {
                p=&h[key];
                while(p->next != NULL) p=p->next;
                p->next=new Hash(fn,en);
            }

        }
        else  //输入外文
        {
            key=ELFhash(str);
            if(!h[key].used) printf("eh\n");
            else
            {
                p=&h[key];
                while(p!=NULL)
                {
                    if(!strcmp(str,p->fn))
                    {
                        printf("%s\n",p->en);
                        break;
                    }
                    else
                    {
                        p=p->next;
                    }
                }
                if(p==NULL) printf("eh\n");  //不匹配的情况,不能少
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值