C++ 如何编程一个针对字符串的双哈希实现?

C++ 如何编程一个针对字符串的双哈希实现?,c++,string-hashing,double-hashing,C++,String Hashing,Double Hashing,大家好,第一次在这里,但我想首先问一下,我对双哈希的理解是否正确 双重散列的工作原理是首先实现一个散列函数,然后检查该点是否打开。如果当前点未打开,则使用第二个散列函数确定另一个点,然后将其乘以当前尝试,然后将其添加到由第一个散列算法确定的索引点 我现在的代码是: unsigned int findPos(hashedObj& x) { int offset = 1; int iteration = 0; unsigned int originalPos = my

大家好,第一次在这里,但我想首先问一下,我对双哈希的理解是否正确

双重散列的工作原理是首先实现一个散列函数,然后检查该点是否打开。如果当前点未打开,则使用第二个散列函数确定另一个点,然后将其乘以当前尝试,然后将其添加到由第一个散列算法确定的索引点

我现在的代码是:

unsigned int findPos(hashedObj& x)
{
    int offset = 1;
    int iteration = 0;
    unsigned int originalPos = myhash1( x );
    unsigned int index = originalPos;
    unsigned int secondPos = myhash2( x );
    while( array[ index ].info != EMPTY && array[ index ].element != x )
    {
        iteration = offset++ * secondPos;
        if ( ( originalPos + iteration ) > array.size( ) )
            index = ( originalPos + iteration ) % array.size( );
        else
            index = originalPos + iteration;
    }
    return ( index );
}

unsigned int hash1( const string& key, const int Tsize )
{
    //start the hashvalue at 0
    unsigned int hashVal = 0;

    //cout<<" the size of the table is: "<< Tsize <<endl;

    //add the ascii value for every word to hashval, multiply by 37 each time
    for ( int i = 0; i < key.length(); i++ )
        hashVal = 37 * hashVal + key[ i ];
    //mod hashval so it remains smaller than the table size
    hashVal %= Tsize;

    //return the itemes index value
    return hashVal;
}
unsigned int findPos(hashedObj&x)
{
int offset=1;
int迭代=0;
无符号int-originalPos=myhash1(x);
无符号整数索引=原始值;
无符号int secondPos=myhash2(x);
while(数组[index].info!=EMPTY&&array[index].element!=x)
{
迭代=偏移量+++*secondPos;
if((originalPos+iteration)>array.size())
index=(originalPos+iteration)%array.size();
其他的
索引=初始值+迭代;
}
收益率(指数);
}
无符号int hash1(常量字符串和键,常量int Tsize)
{
//将hashvalue从0开始
无符号整数hashVal=0;

//cout您的if语句不正确:

if ( ( originalPos + iteration ) > array.size( ) )
    index = ( originalPos + iteration ) % array.size( );
else
    index = originalPos + iteration;
}
应该是:

if ( ( originalPos + iteration ) >= array.size( ) )
    index = ( originalPos + iteration ) % array.size( );
else
    index = originalPos + iteration;
}
或者更好的方法是,由于执行if会浪费比%op更多的时间,而且无论结果如何,答案都是一样的,因此您可以完全取消if:

index = ( originalPos + iteration ) % array.size( );

您的if语句不正确:

if ( ( originalPos + iteration ) > array.size( ) )
    index = ( originalPos + iteration ) % array.size( );
else
    index = originalPos + iteration;
}
应该是:

if ( ( originalPos + iteration ) >= array.size( ) )
    index = ( originalPos + iteration ) % array.size( );
else
    index = originalPos + iteration;
}
或者更好的方法是,由于执行if会浪费比%op更多的时间,而且无论结果如何,答案都是一样的,因此您可以完全取消if:

index = ( originalPos + iteration ) % array.size( );

或者你可以通过说

unsigned int hashkey = myhash1( x );
unsigned int stepSz = myhash2( x );
while( array[ index ].info != EMPTY && array[ index ].element != x )
        hashKey = (hashKey + stepSz) % capacity;
return hashkey;

它在使while循环小得多的同时完成了同样的事情(并且去掉了额外的变量)。我假设您不想允许重复(因此while循环中的第二个条件?)。

或者您可以通过以下方式完全简化它

unsigned int hashkey = myhash1( x );
unsigned int stepSz = myhash2( x );
while( array[ index ].info != EMPTY && array[ index ].element != x )
        hashKey = (hashKey + stepSz) % capacity;
return hashkey;

这在使while循环更小的同时完成了同样的事情(并且去掉了额外的变量)。我假设您不想允许重复(因此while循环中的第二个条件?。

旁注:您可能希望在计算循环中修改哈希值,而不是在计算循环外修改一个mod。例如,
hashVal=(37*hashVal+键[i])%Tsize;
这可以避免可能出现的长字符串溢出。我在返回数字之前就这样做了。问题是,如果使用此函数对“战争与和平”进行哈希运算,可能在到达mod之前就用完了位。我想我明白你们的意思了。我从未想过会发生这种情况,因为它是一个无符号的int。我我只是想评论一下我是如何使用UNIX字典文件的,但是由于未知的原因,我一直在运行SEG错误。我做了你们两个建议的,现在它已经不存在了。我不能投票给你们,因为它不会让我,但是你们这些家伙是很棒的。当然,
(a*b)%c=((a%c)*(b%c))%c
。同样值得注意的是(希望很明显的是)
(a*(b%c))%c
同样可行。不管怎样,只要像我在第一条评论中向您展示的那样将它们链接起来,之后就不用担心了=P.Side注意:您可能希望在计算循环中修改哈希值,而不是在其外部修改一个mod。即
hashVal=(37*hashVal+key[I])%Tsize;
这可以避免可能出现的长字符串溢出。我在返回数字之前就这样做了。问题是,如果使用此函数对“战争与和平”进行哈希运算,可能在到达mod之前就用完了位。我想我明白你们的意思了。我从未想过会发生这种情况,因为它是一个无符号的int。我我只是想评论一下我是如何使用UNIX字典文件的,但是由于未知的原因,我一直在运行SEG错误。我做了你们两个建议的,现在它已经不存在了。我不能投票给你们,因为它不会让我,但是你们这些家伙是很棒的。当然,
(a*b)%c=((a%c)*(b%c))%c
。同样值得注意的是(希望很明显的是)
(a*(b%c))%c
同样可行。不管怎样,只要像我在第一条评论中向您展示的那样将它们链接起来,之后就不用担心了=P。哦,对了,我忘了我们从0开始计数,而不是从1开始计数。哦,对了,我忘了我们从0开始计数,而不是从1开始计数。