【问题标题】:Double hashing function returning wrong value双散列函数返回错误值
【发布时间】:2015-01-28 09:37:26
【问题描述】:

我正在创建一个双哈希映射,但删除功能在插入后不起作用。我遵循相同的格式来增加索引,但它只是没有达到正确的索引。

class RHHM {
    unsigned int hash2( int key ) {

        return key % (M-1) + 1;

    }

    //Private variables

    hashNode ** map;        //Backing array
    unsigned int M;   //Capacity of array

    //If index that key hashes to is empty, insert. Else, replace value at hashed index.
    int insert( int key, char value ) {

        int f = hash( key );
        int f2 = hash2 ( key );
        int p = 0;
        int h = f + (p * f2) % M;

        while( map[h] != NULL ) {

            if( p == M )
                return -1 * p;

            if( map[h]->key == key ) {
                map[h]->value = value;
                return p;
            }
            else {
                ++p;
                h = f + (p * f2) % M;
            }
        }

        map[h] = new hashNode( key, value );
        return p;
    }

int remove( int key, char &value) {

        int f = hash( key );
        int f2 = hash2 ( key );
        int p = 0;                         //Keeps track of how many indexes have been checked
        int h = f + (p * f2) % M;

        while( map[h] != NULL ) {

            if( p  == M )              //If item is not found in table, return false
                return -1 * p;

            if( key == map[h]->key )        //If key is found, break out of loop
                break;
            else {
                ++p;
                h = f + (p * f2) % M;  //Wrap around array if necessary
            }

        }

        if( map[h] == NULL )                //If end of cluster reached, return false
            return -1 * p;

        value = map[h]->value;              //Stores the value of the item to be deleted
        delete map[h];                      //Delete the item the user specified
        map[h] = NULL;
        ++p;
        h = f + (p * f2) % M;
        for( ; map[h] != NULL; h = f + (p * f2) % M) {     //While still in the cluster, remove and     reinsert all items
            int tempKey = map[h]->key;
            char tempValue = map[h]->value;
            delete map[h];
            map[h] = NULL;
            insert(tempKey, tempValue);
            ++p;
        }
        return p;

    }

}

这是我的主要内容:

RHHM bh(10);
bh.insert(0, 'A');
bh.insert(10, 'B');
bh.insert(20, 'C');
bh.print(std::cout);

输出:

<[ 0:A, - , 10:B, 20:C, - , - , - , - , - , - ]>

如您所见,第一个索引散列到 0。由于10 键与0 冲突,双散列(10)应该散列到1,但它的散列到2。 为什么返回错误的值?

【问题讨论】:

  • 为什么说应该是1?
  • 我猜你是对的。它应该散列到 2。无论哪种方式,如果我对删除函数使用相同的增量,为什么它可以工作(也就是在删除后重新散列同一集群中的所有内容)。

标签: c++ dictionary hash double-hashing


【解决方案1】:

这是因为 hash2 函数为键 10 返回值 2。对于 hash2(10),hash2 可以显示为。

return 10 % (10-1) + 1

this 依次由运算符优先级求值为 2 as。

return (10 %(10-1))+1

并且在插入函数中,当发生冲突时,您将 hash2 值添加到哈希值中以获得评估为的新索引。

h= f + ( P * f2 ) % M
h= 0 + (1 * 2 ) % 10 \\ this evaluates to 2.

这就是为什么您将新索引设为 2。

编辑:代码在运算符优先级方面存在一些问题。 第一的 h = f + (p * f2) % M; //必要时环绕数组

这不会环绕数组。因为 % 的优先级高于 +。 f 的值在 [0-M-1] 范围内, (p *f2) % M 的值在 [0-M-1] 范围内。所以上面的表达式可能会计算为 [0-2*M-2] 范围内的值。这适用于代码中的其他此类表达式。这是哈希表中可能缺少某些键的原因。

【讨论】:

  • 我明白了。但是....为什么删除函数在删除指定的项目后没有访问正确的索引以重新散列?
  • 您能否提供一个删除特定项目后所需结果的示例
  • 是的。删除应该重新散列这些项目。删除键 0 后所需的输出是:
  • gman,我添加了括号以确保运算符优先级,并且遇到与以前完全相同的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-28
  • 2011-03-15
  • 2020-11-22
相关资源
最近更新 更多