精华内容
下载资源
问答
  • 这个题处理的数据范围比较大,所以用一般的循环查找肯定是超时,所以就要往哈希表上想,先判断其关键字,让后根据关键字来缩小范围继续进行查找,这样可以省不少时间。 #include <iostream> #include <...

    题目来源:poj 3274

    这个题处理的数据范围比较大,所以用一般的循环查找肯定是超时,所以就要往哈希表上想,先判断其关键字,让后根据关键字来缩小范围继续进行查找,这样可以省不少时间。

    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <vector>
    using namespace std;
    const int maxn = 100010;
    const int maxk = 32;
    int sum[maxn][maxk]; //第 1 头牛到第 i 头的对应属性的和
    const int prime = 14997;
    vector<int> hashLink[prime];
    int n, k; //牛的数目
    
    //判断两头牛对应的属性是否相等
    bool cmp(int a, int b)
    {
        for (int i = 0; i < k; i++)
        {
            if (sum[a][i] != sum[b][i])
            {
                return false;
            }
        }
        return true;
    }
    
    //求出距最远的平衡序列
    int check()
    {
        int maxLen = 0;
        for (int i = 0; i < prime; i++)
        {
            for (int j = 0; j < hashLink[i].size(); i++)
            {
                for (int q = j + 1; q < hashLink[i].size(); q++)
                {
                    if (cmp(hashLink[i][j], hashLink[i][q]))
                    {
                        int res = abs(hashLink[i][j] - hashLink[i][q]);
                        maxLen = max(maxLen, res);
                    }
                }
            }
        }
        return maxLen;
    }
    int main()
    {
        scanf("%d %d", &n, &k);
        int x;
        //处理输入变为二进制
        memset(sum, 0, sizeof(sum));
        for (int i = 1; i <= n; i++)
        {
            cin >> x;
            int col = 0;
            do
            {
                sum[i][col++] = x % 2;
                x /= 2;
            } while (x != 0);
        }
    
        for (int i = 1; i <= n; i++)
        {
            for (int j = 0; j < k; j++)
            {
                sum[i][j] += sum[i - 1][j];
            }
        }
        for (int i = 0; i <= n; i++)
        {
            int original = 0;
            int sub = sum[i][k - 1];
            for (int j = 0; j < k; j++)
            {
                sum[i][j] -= sub;
                original += sum[i][j];
            }
            hashLink[(abs)(original % prime)].push_back(i);
        }
        cout << check() << endl;
        return 0;
    }
    

    WA…

    展开全文
  • 一个简单的实现方法是将对象通过某种运算得到一个整数,再让这个整数除以哈希表的大小,其余数,以此作为对象的存储位置。很多的书上认为,哈希表的大小最好是选择一个大的质数,并且最好不要和2的整数幂接近。...

    Hash Table(哈希表)就是根据对象的特征进行定位的一种数据结构。一个简单的实现方法是将对象通过某种运算得到一个整数,再让这个整数除以哈希表的大小,取其余数,以此作为对象的存储位置。

    很多的书上认为,哈希表的大小最好是选择一个大的质数,并且最好不要和2的整数幂接近。《算法导论》上还认为,最不好的选择是哈希表的大小恰好是2的整数幂,对此的解释是(只记得大意):因为计算机是用二进制存储的,当一个二进制数除以一个2的整数幂的时候,结果就是这个二进制数的后几位,前面的位都丢失了,也就意味着丢失了一部分信息,进而导致哈希表中的元素分布不均匀。

    这个解释看似合理,但我不认同。不光是我,Java开发小组的人也不认同。Java里的HashSet类偏偏就把哈希表的大小设置成2的整数幂。可以设想一下,对于自然数集合中的任意一个数x,对于一个正整数M,难道x mod M为某些值的概率会大些吗?显然不是,因为x是在自然数集合里任选的,当选取的次数非常多时,x mod M的结果应该是平均分布在[0,M-1]中。我认为《算法导论》的错误在于先引入了二进制,其实二进制和哈希表的“碰撞”根本没有什么关系;然后说对除以2^n的余数会丢失位,丢失信息,这显然也不对,因为只要x>=M,x mod M的结果总是要“丢失一些信息的”。照《算法导论》的说法,如果计算机采用十进制,那哈希表的容量是10^n的话岂不是很糟?这种解释显然站不住脚。

    我认为对于x mod M这样的哈希函数来说,好坏应该取决于x的生成方式和M的值。比如一个字符串“ABC”,如果我让x("ABC")=65128^2+66128+67,即把字符串当成一个128进制的整数,那么若M=128,那就很糟糕了。因为这样无论是什么字符串,最终结果只取决于最后一个字符,这才会造成分布不均匀。

    展开全文
  • 哈希表的实现(取余法

    千次阅读 2014-08-22 13:53:00
    哈希表,又叫散列表

        哈希表,又叫散列表,它可以提供快速的插入查找操作,对于大规模数据的查找时间空间效率会很高。哈希表构造方式有多种,其中取余法在比赛中最常用。

        如果读入很多值非常大的数,让你判断一些数是否出现过。如果用桶来记录,空间开不了那么大。如果排序后来查,时间效率又低。但可以通过hash优化解决这个问题。

        取余法简单地说,就是给每个数mod一个合适的值X,得到的余数放在数组中下标与其一致的位置,由于X不会很大,且余数不会超过数X,数组的大小在0..X-1范围内,不会超空间,如果查某个数,将这个数mod X后在直接在数组中找到。

        但是这样一些不同数据会出现在同一个地址上,比如说X=5,13 mod X=3,18 mod 5=3,这两个数(13,18)便产生了冲突。

        为了解决冲突,可以使用挂链的形式,将冲突数据像挂链一样挂在同一位置,将13放在5的位置,将18挂在13后面,如果要查18,先18 mod 5=3 找到3的位置,先看3位置挂链上的第一个数是13,不等于18,继续往后面找,直到找到18,如果找不到,说明没有出现,按要求输出即可。我们可以发现,这样的存储方式很像(或者就是)链表的存储方式,所以我们可以使用链表来处理“挂链”的部分。这样查找的问题就解决了。

         经分析可以得知,hash表查找时间最好为O(1),最差为O(n),由于O(n)情况对于比赛的数据一般不会出现,如果选择了合适的X值,时间效率会非常好。

         如何选择X值呢,通常是选一个较大但不会使数组超空间的质数。 


    具体实现:

    初始化

    type
      hash=^node;
         node=record
           dx:int64;
           next:hash;
         end;        


    插入操作

    procedure put(x:int64);
    var q:hash;xx:int64;
    begin
       xx:=x mod maxn;//maxn就是那个适当的正整数X
       new(q);
       q^.dx:=x; q^.next:=a[xx];
       a[xx]:=q;
    end;          


    查找操作

    function find(x:int64):boolean;
    var p:hash;
    begin
      xx:=x mod maxn;
      new(p);
      p:=a[xx];
      while p<>nil do
      begin
        if p^.dx=x then exit(true);
        p:=p^.next;
      end;
      exit(false);
    end;          


    展开全文
  • 《算法精解:C语言描述》上提到的一种简单的将键值k映射到m槽位...当m不是素数时在散列分布时也会增加分布不均匀的机会,总的来说哈希函数的设计尽量使键值均匀、随机地分布在中,其他方法可以参考《算法导论》。
    《算法精解:C语言描述》上提到的一种简单的将键值k映射到m槽位的方法:h(k)=k mod m。
    
    而该书上写了一段话:“通常情况下,要避免m取2的幂,因为假设m=2^p,则h(k)是k的二进制数的低p位......,通常选择m会是一个素数,而且不那么靠近2的幂......”。这段话理由是:

    以 m = 2^3 = 8 为例,如下图所示:


    从概率的角度,出现相同的概率比较高,而通常我们希望 h(k) 的值依赖于 k 的所有位而不是最低 p 位,因为这样才会使得散列表看起来更均匀。当m不是素数时在散列分布时也会增加分布不均匀的机会,总的来说哈希函数的设计尽量使键值均匀、随机地分布在表中,其他方法可以参考《算法导论》。
    展开全文
  • ...通过上面的分析,现在就很明确了,如果给我们随机的数列放到哈希表中,如何保障它能尽量减少冲突呢,就需要模的因子最少,而因子最少的就是素数了,这就是为什么哈希表取模为素数的原因了。 ...
  • #define p 13//除留余数法的除数,一般是比m小的最大素数H(key)=key mod p typedef struct Hash { int key;//关键字 //InfoType otherinfo;//其他数据项 }Hash, HashTable[m]; void InitHashTable(HashTable ht)...
  • 哈希取余法哈希表大小质数的问题 hashing | planetmath.orghttp://planetmath.org/node/33326 good hash table primes | planetmath.orghttp://planetmath.org/goodhashtableprimes 哈希函数取余法除数为何要...
  • 除留取余,就是哈希函数将关键字被某个不大于哈希表长m的数p除后所得余数为哈希地址。这是最常用、也最简单的构造哈希函数的方法。当然,也可以对关键字直接取模,也可以折叠、平方中等运算后取模。那么问题来了,...
  • //除留取余法,根据前辈们的经验,若哈希表长为M,则取余因子P为小于 //或等于表长(最好接近M)的最小质数或不包含小于20质因子的合数 } //插入关键字到哈希表 Status InsertHashTable( HashTable* pHashTable,...
  • c实现的哈希表。哈希函数采用除留余数法,处理哈希冲突采用链地址法。包含设计文档!在dev c++上验证过。
  • //哈希函数的构造方法:除留取余法 //处理冲突机制:链地址法 typedef struct _NODE { int key; struct _NODE* next; }_NODE; typedef struct Hash_Table { _NODE* pChainHash[13]; }Hash_Table; //初始化哈
  • // 由于 通过哈希函数 计算后的地址重复几率很小,所以把重复部分用顺序来存放,查找时遍历这个公共溢出区的顺序,效率会更高。 void Init(HashTable *p) { p->element = (int*)malloc(sizeof(int)*HASHSIZE); ...
  • 哈希--直接定值法和除留取余法

    千次阅读 2017-08-07 16:38:15
    1. 哈希是一种算法,哈希表是用哈希算法构造出来的一种数据结构 2. 哈希算方法的几种方法 直接定值法 这里有一个例题,就是我们想判断某一字符串中,某一个字符出现的个数,我们可以使用哈希的思想,就是...
  • 本题要找通话次数最多的号码,如果这样的号码不唯一,就找最小的号码,想到用哈希表进行存储。   代码如下: 1 // 本题采用除留取余法构造哈希函数,使用分离链表法解决冲突 2 3 #include 4 ...
  • 实现哈希表查找(除留余数法)

    万次阅读 2017-03-22 17:51:47
    哈希表也称散列表,查找有两种方式,比较式查找和计算式查找,而计算式查找则通过哈希表来实现。给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为...
  • 哈希表+哈希桶简介及实现

    千次阅读 多人点赞 2020-08-01 22:44:47
    一文看懂哈希表,理解哈希桶。
  • 哈希表的大小为什么最好为素数1、哈希表基本概念2、为什么哈希表大小最好为素数2.1通过实例分析1、取哈希表大小(‘模’) M = 6 和 M = 72、几种不同的Array3、哈希表Array1 & M = 6(6次冲突)Array1 & ...
  • MIT算法导论学习第七讲+第八讲:哈希表-1哈希表的定义哈希表,又称散列表,其定义是根据一个哈希函数将集合S中的关键字映射到一个表中,这个表就称为哈希表,而这种方法就称为Hashing。1.1引入哈希表我们先来一个...
  • 哈希表 Hash表也称散列表,也可以直接译作哈希表,Hash表是一种根据关键字值(key - value)映射到表中的一个位置而直接进行访问的数据结构,这个映射函数叫散列函数(哈希函数) (链地址法哈希表哈希表基于...
  • 数据结构学习笔记(七):哈希表(Hash Table)

    多人点赞 热门讨论 2021-06-25 18:06:20
    1 哈希表的含义与结构特点 1.1 哈希(Hash)即无序 哈希表(Hash Table)更直观的中文名字是散列表,存储在里面的元素不是单个的,而是成对的,这就是我们熟悉的键值对(key-value pair)。Java中的Map(映射)、...
  • 哈希查找

    2017-10-02 15:56:10
    哈希查找时通过建立被查找元素(key)与其存储位置的函数关系f,根据address=f(key)...常用于的哈希函数有:除数余法、平方中法、直接定址法等 常用解决地址冲突的方法有:开放地址法h=(h(key)+d);链地址法;
  • 散列表(Hash table)通过将关键码映射到中的某个位置来存储元素,然后根据关键码用同样的方式进行直接访问 散列表 理想的搜索方法是可以不经过任何比较,一次直接从中得到要搜索的元素。如果构造一种存储...
  • 正在学习数据结构里的散列相关知识,书里一般都会提到,如果用除留余数的散列函数,最好选择素数作为除数。但没有对此详细的证明。 对此不太理解,个人理解是,无论素数还是合数,在取模的一个周期内都是均匀分布...
  • 通俗理解“哈希表

    千次阅读 2018-06-20 21:25:14
    for=pc今天聊聊「哈希表」,「哈希表」主要作用在于高效查找。在编程实现中,常常面临着两个问题:存储和查找,存储和查找的效率往往决定了整个程序的效率。脑补下,你在家里忘记了指甲刀放在哪里,通常要在你家所有...
  • 一.哈希概念
  • 哈希函数 直接定址法 除留余数法

    千次阅读 2019-06-29 20:18:00
    直接定址法 ...例1,有一个人口统计,记录了从1岁到100岁的人口数目,其中年龄作为关键字,哈希函数关键字本身,如图(1): 地址 A1 A2 …… A99 A100 ...
  • 以前在美国学Java数据结构的时候,因为当时是插班生,临时选的数据结构,其实当时还没学Java,听到hash ...一、哈希和哈希表 二、哈希思想在信息领域的应用 三、哈希的设计和性质 四、常用的哈希函数 五、冲突消解技术
  • 哈希表(开放定址法处理冲突) 采用除留余数法(H(key)=key %n)建立长度为n的哈希表,处理冲突用开放定址法的线性探测。 输入 第一行为哈希表的长度n; 第二行为关键字的个数; 第三行为关键字集合; 第三行为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 441
精华内容 176
关键字:

哈希表除数取余法