【问题标题】:How can i count the collisions in this hash function?我如何计算这个哈希函数中的冲突?
【发布时间】:2011-12-05 23:41:38
【问题描述】:

这是一个前缀散列函数。我想计算这种方法中的碰撞次数,但我不知道该怎么做。看起来它可能很简单,但我想不出一个很好的方法来做到这一点......

int HashTable_qp::preHash(string & key, int tableSize )
{
    string pad = "AA";
    //some words in the input are less than 3 letters
    //I choose to pad the string with A because all padded characters 
    //have same ascii val, which is low, and will hopefully alter the results less
    if (key.length() < 3)
    {
        key.append(pad);
    }
    return ( key[0] + 27 * key[1] + 729 * key[2] ) % tableSize;
}

【问题讨论】:

  • 创建一个无符号直方图 [tablesize],生成一些(所有)可能的字符串并计算它们的 hashval,并相应地更新直方图 histogram[hashval] +=1;
  • @wildplasser,这将是最简单的方法。我的回答会更快。如果它不是性能关键,我会选择 wild 的 想法。 (您可能应该将其发布为答案,以帮助其他人在找到此页面时找到它。)

标签: c++ hash prefix hash-collision


【解决方案1】:

如果它是一个数组作为底层数据结构: int hash = preHash(&key, array.length); if(array[hash] != null) this.count++; 如果它是一个链表数组,那么:

if(array[hash] != null && *(array[hash]) != null)
this.count++

如果您只能访问 stl 库,我相信只是测试该元素是 null 在调用散列函数之后添加之前就足够了。

【讨论】:

  • 我正在使用 stl,你能告诉我考虑到 stl 的效果吗?
  • 最简单的方法是继承它并覆盖它在派生类中调用:HashTable_qt::PreHash,但实例化派生类并为其赋值并给派生类一个名为CollisionCount的字段变量及之前您添加一个新值,将其初始化为 0,然后在调用它之后,如果大于 1,则使用新键调用函数应该具有新值
  • int Prehash(string & key, int tableSize) { HashMap_qt::Prehash(key, tablesize);碰撞计数++; } in main HashTable_qt2* map = new HashMap_qt2() map.CollisionCount = 0;地图。添加(...); cout
【解决方案2】:

创建直方图:

 unsigned histogram[tablesize] = {0};

生成一些(所有)可能的字符串并计算它们的 hashval,并相应地更新直方图:

for(iter=0; iter < somevalue; iter++) {
 hashval = hashfunc( string.iterate(iter) ); // I don't know c++
 histogram[hashval] +=1;
 }

现在您必须分析块/簇的哈希表。经验法则是,对于 (tablesize==iter),您预计大约 30% 的单元格计数 =1,大约 30% 为空;其余的有两个或更多。

如果您将所有(count*(count+1))/2 相加,然后除以表大小,您应该期望得到大约 1.5。一个坏的散列函数会给出更高的值,一个完美的散列只会有 count=1 的单元格(因此:ratio=1) 使用线性探测,你当然不应该使用 tablesize=niter,而是让 tablesize 更大,比如两倍大。不过,您可以使用相同的指标(探测数/条目数)来分析其性能。

更新:关于哈希函数及其性能的精彩介绍可以在 http://www.strchr.com/hash_functions 找到。

【讨论】:

    【解决方案3】:

    您可以创建一个整数数组,每个整数代表一个哈希值。当您完成使哈希循环返回嵌套循环中的数组时。如果你有以下数组,

    [0] -> 13
    [1] -> 5
    [2] -> 12
    [3] -> 7
    [4] -> 5
    

    对于 0..n 中的每个项目 i,检查项目 i+1..n 是否匹配。在英语中,这将是:检查每个元素是否等于 after 它的任何元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-15
      • 1970-01-01
      • 2018-10-08
      • 2019-03-25
      • 2014-10-02
      相关资源
      最近更新 更多