字符串哈希之散列表处理冲突 poj1880

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define M 100001
#define N 100

struct node       //链表数组
{
    int id;
    struct node *next;
}*d[M];  

char a[M][N],b[M][N];
char s[N],str[N];

unsigned int ELFHash(char *str)
{
    unsigned int hash=0;
    unsigned int x=0;
    while(*str)
    {
        hash=(hash<<4)+(*str++);
        if((x=hash&0xF0000000L)!=0)
        {
            hash^=(x>>24);
            hash&=~x;
        }
    }
    return hash%M;
}
int main()
{
    int i=0;
    struct node *p;
    while(scanf("%s",str),strcmp("@[email protected]",str))
    {
        int len=strlen(str);
        str[len-1]=‘\0‘;
        strcpy(a[i],str+1); //前一个字符串处理
        gets(str);          //后一个字符串处理
        strcpy(b[i],str+1);

        int hash=ELFHash(b[i]);  //后一个字符串的映射
        p=(struct node *)malloc(sizeof(struct node));//创建动态链表p
        p->id=i;          //给值
        p->next=d[hash];  //给链表数组的第hash个链表给首地址
        d[hash]=p;        //将链表p的首地址付给链表数组的第hash个链表

        hash=ELFHash(a[i]);    //前一个字符串的映射,两个字符串的i值相同
        p=(struct node *)malloc(sizeof(struct node));
        p->id=i;
        p->next=d[hash];
        d[hash]=p;
        i++;
    }
    int n;
    scanf("%d",&n);
    getchar();
    while(n--)
    {
        gets(str);
        if(str[0]==‘[‘)
        {
            int len=strlen(str);
            str[len-1]=‘\0‘;
            strcpy(s,str+1);
        }
        else
            strcpy(s,str);
        int hash=ELFHash(s);
        p=d[hash];
        int flag1=1,flag2=1;
        while(p)
        {
            if(strcmp(b[p->id],s)==0)
            {
                flag1=0;
                break;
            }
            if(strcmp(a[p->id],s)==0)
            {
                flag2=0;
                break;
            }
            p=p->next;
        }
        if(p)
        {
            if(flag1==0)
                printf("%s\n",a[p->id]);
            else
                printf("%s\n",b[p->id]);
        }
        else
            printf("what?\n");
    }
    return 0;
}
时间: 2024-10-13 20:56:20

字符串哈希之散列表处理冲突 poj1880的相关文章

哈希表/散列表

哈希表/散列表,是根据关键字(key)直接访问在内存存储位置的数据结构. 构造哈希表的常用方法: 直接地址法---取关键字的某个线性函数为散列地址,Hash(Key) = Key或Hash(key) = A*Key + B, A,B为常数. 除留余数法---取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址. Hash(key) = key % p. 若采用直接地址法(Hash(Key) = Key)存在一定的缺陷. 当Key值特别大时,而Key之前的数很少,就会造成空间浪费.大多时

HashTable-哈希表/散列表

HashTable-散列表/哈希表,是根据关键字(key)而直接访问在内存存储位置的数据结构.它通过一个关键值的函数将所需的数据映射到表中的位置来访问数据,这个映射函数叫做散列函数,存放记录的数组叫做散列表. 构造哈希表的几种方法 直接定址法--取关键字的某个线性函数为散列地址,Hash(Key)= Key 或 Hash(Key)= A*Key + B,A.B为常数. 除留余数法--取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址.Hash(Key)= Key % P. 平方取中法

散列表(一).散列表基本内容介绍

一说到散列表,大家脑子想到的词就是:Hashmap.key-value.查找速度快.增删速度快等等.确实,在我们平常的学习生活中,散列表是很常见.也是用的很多的数据结构.那么散列表是怎样设计出来的,为什么它既可以和数组一样查询快,又可以和链表一样快增删,本节让我们一起了解一下什么是散列表.什么是散列函数.它究竟是如何设计出来的. 散列思想 什么是散列思想呢?散列表还有一个英文名叫做Hashtable,也叫做"哈希表"."hash表",hash我们都了解,是同过一定的

数据结构之散列表总结

散列表的概念 注意:    ①由同一个散列函数.不同的解决冲突方法构造的散列表,其平均查找长度是不相同的.     ②散列表的平均查找长度不是结点个数n的函数,而是装填因子α(填入表中的记录个数/散列表的槽数    n/m).因此在设计散列表时可选择α以控制散列表的平均查找长度.(平均查找长度=总查找(插入)/记录个数)          通过链接法解决冲突:成功查找的期望查找长度O(1+a), 不成功查找的平均查找长度也为O(1+a).         开放寻址解决冲突:引入探查序列,对于a<

算法导论 第11章 散列表

散列表是主要支持动态集合的插入.搜索和删除等操作,其查找元素的时间在最坏情况下是O(n),但是在是实际情况中,散列表查找的期望是时间是O(1),散列表是普通数组的推广,因为可以通过元素的关键字对数组进行直接定位,所以能够在O(1)时间内访问数组的任意元素. 1.直接寻址表 当关键字的全域较小,即所有可能的关键字的量比较小时,可以建立一个数组,为所有可能的关键字都预留一个空间,这样就可以很快的根据关键字直接找到对应元素,这就是直接寻址表,在直接寻址表的查找.插入和删除操作都是O(1)的时间.. 2

散列表之完美散列

散列表之完美散列 完美散列perfect hashing 两级散列法 gperf工具来自动生成完美散列函数 gperf的安装 gperf关键字文件的书写格式 gperf应用举例 注意 本文中的所有代码你都可以在这里: https://github.com/qeesung/algorithm/tree/master/chapter11/11-5/gperf(这里会及时更新) 或者是这里: http://download.csdn.net/detail/ii1245712564/8936303 找到

大话数据结构—散列表查找(哈希表)

一.基本概念 散列技术:在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key). f:散列函数/哈希函数: 采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表. 关键字对应的记录存储位置称为散列地址. 散列技术既是一种存储方法,也是一种查找方法. 散列技术适合求解问题是查找与给定值相等的记录.查找速度快. 散列技术不适合范围查找,不适合查找同样关键字的记录,不适合获取记录的排序,最值. 冲突:关键字key1不等于k

用Hash Table(哈希散列表)实现统计文本每个单词重复次数(频率)

哈希表在查找方面有非常大应用价值,本文记录一下利用哈希散列表来统计文本文件中每个单词出现的重复次数,这个需求当然用NLP技术也很容易实现. 一.基本介绍 1.Hash Key值:将每个单词按照字母组成通过一个乘子循环运算得出一个小于29989的整数,29989是一个比较大的质数.0~29989即为Key值. 2.哈希函数: 1 //哈希函数 2 unsigned int hashIndex(const char* pWord) //返回hash表的索引(即hash指针数组的下标) 3 { 4 a

漫画 | 什么是散列表(哈希表)?

创建与输入数组相等长度的新数组,作为直接寻址表.两数之和的期望是Target,将Target依次减输入数组的元素,得到的值和直接寻址表比较,如果寻址表存在这个值则返回:如果不存在这个值则将输入数组中的元素插入寻址表,再进行输入数组中的下一个元素. 再进一步优化可以将输入数组直接作为直接寻址表,控制对应的下标就好,代码如下: Code:直接寻址表 class Solution { public int[] twoSum(int[] nums, int target) { for (int i =