`

哈希Hash

 
阅读更多

     要点一:哈希表长度 的确定是个两难的问题:太短则容易造成冲突(POJ->TLE);太长则浪费存储空间(POJ->MLE)。另外,有兴趣看一下“最小完美哈希函数”

     要点二:哈希冲突 是必须解决的问题,主要有一下几种解决方案

                (1)开放定址法 :当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。沿此序列逐个单元地查找,直到找到给定 的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。查找时探查到开放的 地址则表明表中无待查的关键字,即查找失败。

                (2)链地址法 :将所有关键字相同的节点链接在同一个单链表中。

                (3)再哈希法 :当发生冲突时,使用第二个、第三个、哈希函数计算地址,直到无冲突

                (4)建立一个公共溢出区 :假设哈希函数的值域为[0,m-1],则设向量HashTable[0..m-1]为基本表,另外设立存储空间向量OverTable[0..v]用以存储发生冲突的记录。

 

     其实这个东西很简单,主要要熟悉实现方法。下面直接上几个例题:

 

注:代码中尚未解决hash溢出问题!!!

 

POJ 2503 Babelfish ==>  http://poj.org/problem?id=2503

C++代码(开放地址,线性探查

//poj 2503 Babelfish 

#include <iostream>        //ELFhash函数是对字符串的散列
#include <string>
using namespace std;
#define M 1000000
//M如果较小则不能很好地避免冲突,解决冲突需要更多的时间,会TLE,比如200000 当然不能过大,会MLE,比如10000000
//M取适合的值,既可以避免hash开得太大,同时又可以减少冲突 
string hash[M],res[M];
int ELFHash(string str)        //ELFhash函数
{
    int h = 0;
    int x  = 0;
    for(int i=0;i<str.size();++i)
    {
        h = (h << 4) + (str[i]);
        if ((x = h & 0xF0000000L) != 0)
        {
            h ^= (x >> 24);
            h &= ~x;
        }
    }
    return h % M;
}

int main()
{

    string str,e,f,s;
    int ind;
    while(getline(cin,str))     //如果输入某行是“直接回车”的话,则str="",while("")导致退出循环
    {
        if(str.size()==0)
            break;
        int pos=str.find(' ');
        e.assign(str,0,pos);    //添加从下标[0]开始的pos个字符
        f.assign(str,pos+1,str.size()-1-pos);    
        
        ind=ELFHash(f);
        while(hash[ind]!="")
            ind=(ind+1)%M;
        hash[ind]=f;
        res[ind]=e;
    }
    while(cin>>s)
    {
        ind=ELFHash(s);
        if(hash[ind]=="")
            cout<<"eh\n";    
        else
        {
            while(hash[ind]!=s && hash[ind]!="")
                ind=(ind+1)%M;        //开放地址法 线性探查法
            if(res[ind]!=""){
                cout<<res[ind]<<endl;
            }else{
                cout<<"eh\n";
            }
        }
    }
    return 0;
}

 

C++代码: (链地址法

#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;
}
 

 

 

 

 

分享到:
评论

相关推荐

    哈希hash信息查看器

    哈希(Hash)信息查看器是一种实用工具,主要用于验证文件的完整性和一致性。在IT行业中,哈希值扮演着至关重要的角色,它是一种通过特定算法将任意大小的数据转化为固定长度输出的唯一标识符。这个输出通常称为哈希...

    杂凑表的设计与实现 数据结构 哈希 hash

    哈希表,又称散列表,是一种高效的数据存储和检索结构,它通过特定的函数(哈希函数)将数据映射到一个固定大小的数组中,从而实现快速查找。在这个问题中,我们需要设计一个哈希表来存储班级的人名,每个名字用汉语...

    Hash值查看以及修改软件(Hash_1.0.4_0523.exe以及HashModifier.exe)

    在IT领域,Hash值是一种广泛使用的数据校验方式,它能够为任何大小的文件生成一个固定长度的唯一标识,这个标识通常称为哈希值或散列值。Hash值查看及修改软件,如"Hash_1.0.4_0523.exe"和"HashModifier.exe",是...

    C语言实现散列表(哈希Hash表)实例详解

    C语言实现散列表(哈希Hash表)实例详解 散列表(哈希Hash表)是一种常用的数据结构,它可以快速地查找、插入和删除数据。在C语言中,实现散列表可以使用数组和链表等数据结构。本文将详细介绍C语言实现散列表...

    哈希算法Hash

    哈希算法 Hash 哈希算法 Hash 是一种常用的数据加密技术,用于将任意长度的数据转换为固定长度的哈希值。哈希算法 Hash 的设计目的是为了实现数据的加密和身份验证。下面我们将对哈希算法 Hash 进行详细的介绍和...

    hash.rar_HASH算法_fpga hash_hash_zebra85v_哈希表Verilog

    标题中的“hash.rar_HASH算法_fpga hash_hash_zebra85v_哈希表Verilog”揭示了这个压缩包文件的主要内容,它涉及到哈希(Hash)算法在高速Field-Programmable Gate Array(FPGA)上的实现,以及与Zebra85v硬件平台和...

    链式哈希表hash

    哈希表(Hash Table)的核心思想是通过哈希函数将数据的关键字(key)映射到一个固定大小的数组中,使得查找、插入和删除操作的时间复杂度可以接近O(1)。 哈希函数是链式哈希表中的关键部分,它的主要任务是将...

    基于python与感知哈希算法实现图像检索

    此外,还可以考虑扩展到其他哈希算法,如平均色彩哈希(Average Hash)、差分色彩哈希(Difference Hash)和结构相似性哈希(Structure Hash)。每种方法都有其特点和适用场景,选择合适的哈希算法对于优化图像检索...

    哈希计算工具 java-hash

    哈希计算工具 `java-hash` 是一款基于Java编程语言实现的专门用于进行哈希值计算的软件。在软件开发和信息安全领域,哈希算法扮演着至关重要的角色,它能够将任意长度的数据转换为固定长度的输出,这个输出被称为...

    Hash Caculator 哈希值计算工具

    哈希值计算工具,如标题所示的"Hash Calculator",是一种用于验证数据完整性和一致性的实用程序。在信息技术领域,哈希(Hash)是通过特定算法将任意长度的数据转化为固定长度输出的过程。这个过程通常不可逆,即从...

    哈希映射 hash map

    哈希映射(Hash Map),又称为哈希表,是一种数据结构,用于高效地存储和检索键值对。它基于哈希表的概念,利用哈希函数将键(Key)映射到一个固定大小的数组(桶)中的特定位置,以此实现快速访问。哈希表最大的...

    hash code 一种常用的哈希算法

    哈希码(Hash Code)是一种在计算机科学中广泛使用的数据处理技术,主要应用于查找和存储。标题中的"hash code"指的是这种技术,特别是在Java中的`Hashtable`类中的应用。哈希函数是哈希码的核心,它能够将任意大小...

    MD5-Hash哈希值计算工具

    MD5-Hash哈希值计算工具 当前程序版本:1.8 更新介绍: 1.8版增加了停止按钮(取消当前计算进程),修复了文件大小判断出错的问题。 1.7版增加了保存哈希值验证结果到文本的功能,更换了程序图标。 1.6版改进了验证时...

    C语言实现的Hash哈希表

    哈希表(Hash Table)是一种数据结构,它通过哈希函数将关键字映射到数组的索引位置,以此实现快速的查找、插入和删除操作。在C语言中实现哈希表,我们需要理解哈希函数的设计、冲突解决策略以及动态扩容等核心概念...

    python 密码学示例——理解哈希(Hash)算法

    哈希(Hash)算法在密码学中扮演着至关重要的角色,它是确保数据保密性和完整性的核心工具。哈希算法是一种单向函数,它将任意长度的输入(也称为预映像)转化为固定长度的输出,这个输出被称为哈希值或消息摘要。...

    HashTools哈希值计算工具

    哈希值计算工具,如HashTools,是IT领域中一种重要的数据校验工具。它能够对文件内容进行精确的计算,生成一个固定长度的哈希值,这个值就像文件的数字指纹,对于验证文件的完整性和原始性至关重要。在本篇文章中,...

    Hash map 哈希表

    哈希表,也被称为Hash Map,是计算机科学中一种高效的数据结构,用于存储键值对。它通过一种称为哈希函数的过程将键映射到数组的特定位置,从而实现快速的查找、插入和删除操作。在哈希表中,查找时间通常接近常数...

    哈希表应用C++_STL_hash

    通过`std::hash`模板类的特化或者`std::unordered_set/map`的`hash_function`成员函数进行设置。 - **等价关系**:对于`std::unordered_map`,键的等价关系默认由`==`运算符决定。如果需要自定义,可以提供一个比较...

Global site tag (gtag.js) - Google Analytics