Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 双探针哈希表_C++_Hashtable_Double Hashing - Fatal编程技术网

C++ 双探针哈希表

C++ 双探针哈希表,c++,hashtable,double-hashing,C++,Hashtable,Double Hashing,我试图编辑我的哈希表以形成一个双哈希类,但似乎无法正确地得到它 我想知道是否有人有什么见解。有人告诉我,我所需要做的就是编辑findPos(),现在我必须使用新策略提供新的探测 **我做了一些研究,它说在双重探测中,你会使用R-(x mod R),其中R>大小和一个比表大小小的素数。那么,我是否要创建一个新的重新灰化函数 这是我的密码: template <typename HashedObj> class HashTable { public: explicit Has

我试图编辑我的哈希表以形成一个双哈希类,但似乎无法正确地得到它

我想知道是否有人有什么见解。有人告诉我,我所需要做的就是编辑findPos(),现在我必须使用新策略提供新的探测

**我做了一些研究,它说在双重探测中,你会使用R-(x mod R),其中R>大小和一个比表大小小的素数。那么,我是否要创建一个新的重新灰化函数

这是我的密码:

template <typename HashedObj>
class HashTable
{
  public:
    explicit HashTable( int size = 101 ) : array( nextPrime( size ) )
      { makeEmpty( ); }

    bool contains( const HashedObj & x ) const
    {
        return isActive( findPos( x ) );
    }

    void makeEmpty( )
    {
        currentSize = 0;
        for( auto & entry : array )
            entry.info = EMPTY;
    }

    bool insert( const HashedObj & x )
    {
            // Insert x as active
        int currentPos = findPos( x );
        if( isActive( currentPos ) )
            return false;

        if( array[ currentPos ].info != DELETED )
            ++currentSize;

        array[ currentPos ].element = x;
        array[ currentPos ].info = ACTIVE;
            // Rehash; 
        if( currentSize > array.size( ) / 2 )
            rehash( );
        return true;
    }

    bool insert( HashedObj && x )
    {
            // Insert x as active
        int currentPos = findPos( x );
        if( isActive( currentPos ) )
            return false;

        if( array[ currentPos ].info != DELETED )
            ++currentSize;

        array[ currentPos ] = std::move( x );
        array[ currentPos ].info = ACTIVE;

            // Rehash; see Section 5.5
        if( currentSize > array.size( ) / 2 )
            rehash( );

        return true;
    }

    bool remove( const HashedObj & x )
    {
        int currentPos = findPos( x );
        if( !isActive( currentPos ) )
            return false;

        array[ currentPos ].info = DELETED;
        return true;
    }

    enum EntryType { ACTIVE, EMPTY, DELETED };

  private:
    struct HashEntry
    {
        HashedObj element;
        EntryType info;

        HashEntry( const HashedObj & e = HashedObj{ }, EntryType i = EMPTY )
          : element{ e }, info{ i } { }

        HashEntry( HashedObj && e, EntryType i = EMPTY )
          : element{ std::move( e ) }, info{ i } { }
    };

    vector<HashEntry> array;
    int currentSize;

    bool isActive( int currentPos ) const
      { return array[ currentPos ].info == ACTIVE; }

    int findPos( const HashedObj & x ) const
    {
        int offset = 1;
        int currentPos = myhash( x );

        while( array[ currentPos ].info != EMPTY &&
               array[ currentPos ].element != x )
        {
            currentPos += offset;  // Compute ith probe
            offset += 2;
            if( currentPos >= array.size( ) )
                currentPos -= array.size( );
        }

        return currentPos;
    }

    void rehash( )
    {
        vector<HashEntry> oldArray = array;

            // Create new double-sized, empty table
        array.resize( nextPrime( 2 * oldArray.size( ) ) );
        for( auto & entry : array )
            entry.info = EMPTY;

            // Copy table over
        currentSize = 0;
        for( auto & entry : oldArray )
            if( entry.info == ACTIVE )
                insert( std::move( entry.element ) );
    }

    size_t myhash( const HashedObj & x ) const
    {
        static hash<HashedObj> hf;
        return hf( x ) % array.size( );
    }
};
模板
类哈希表
{
公众:
显式哈希表(int size=101):数组(nexttime(size))
{makeEmpty();}
布尔包含(常量HashedObj&x)常量
{
返回isActive(findPos(x));
}
void makeEmpty()
{
currentSize=0;
用于(自动输入:阵列(&T)
entry.info=空;
}
布尔插入(常量HashedObj&x)
{
//将x插入为活动状态
int currentPos=findPos(x);
如果(isActive(currentPos))
返回false;
if(数组[currentPos].info!=已删除)
++电流大小;
数组[currentPos]。元素=x;
数组[currentPos].info=活动;
//再灰化;
if(currentSize>array.size()/2)
再灰化();
返回true;
}
布尔插入(HashedObj&&x)
{
//将x插入为活动状态
int currentPos=findPos(x);
如果(isActive(currentPos))
返回false;
if(数组[currentPos].info!=已删除)
++电流大小;
数组[currentPos]=std::move(x);
数组[currentPos].info=活动;
//重新灰化;见第5.5节
if(currentSize>array.size()/2)
再灰化();
返回true;
}
bool remove(常量HashedObj&x)
{
int currentPos=findPos(x);
如果(!isActive(currentPos))
返回false;
数组[currentPos].info=已删除;
返回true;
}
枚举入口类型{活动,空,已删除};
私人:
结构哈希项
{
HashedObj元素;
入口类型信息;
HashEntry(const HashedObj&e=HashedObj{},EntryType i=EMPTY)
:元素{e},信息{i}{
HashEntry(HashedObj&&e,EntryType i=EMPTY)
:元素{std::move(e)},信息{i}{
};
矢量阵列;
int-currentSize;
布尔isActive(int currentPos)常量
{返回数组[currentPos].info==活动;}
int findPos(常量HashedObj&x)常量
{
int offset=1;
int currentPos=myhash(x);
while(数组[currentPos].info!=空&&
数组[currentPos]。元素!=x)
{
currentPos+=偏移量;//计算第i个探针
偏移量+=2;
if(currentPos>=array.size())
currentPos-=array.size();
}
返回当前位置;
}
无效再灰分()
{
向量数组=数组;
//创建新的双尺寸空表
resize(nexttime(2*oldArray.size());
用于(自动输入:阵列(&T)
entry.info=空;
//把表格抄过来
currentSize=0;
用于(自动输入:oldArray(&T)
如果(entry.info==活动)
插入(std::move(entry.element));
}
大小\u t myhash(常量HashedObj&x)常量
{
静态hash-hf;
返回hf(x)%array.size();
}
};

我不确定是否理解您的代码,但让我提出一些意见,这些意见不应被视为答案,但其规模大于允许评论的内容

  • 如果您使用二次探测,那么我认为在方法
    findPos()
    中,您应该将
    currentPos
    作为
    currentPos*currentPos%array.size()。目前,如我所见,在一个单位内增加
    currentPos
    offset
    最初为1),在2个单位后,在4个单位后,依此类推
  • 可能您正在尝试一种计算二次探头的快速方法。如果是这种情况,则偏移量不应增加2,而应乘以2。这可能是因为
    offset*=2
    ,但是因为您应该计算碰撞的数量,所以应该增加
    offset
  • 也许更简单的方法是:

    currentPos+=2*偏移量++-1;//快速实现二次分辨率的方法

  • 您的大小调整是可以的,因为它保证表至少有一半是空的,因此在执行插入时搜索可用条目是可以保证的


    祝您好运

    我不确定是否理解您的代码,但让我提出一些意见,这些意见不应被视为答案,但其规模大于允许评论的内容

  • 如果您使用二次探测,那么我认为在方法
    findPos()
    中,您应该将
    currentPos
    作为
    currentPos*currentPos%array.size()。目前,如我所见,在一个单位内增加
    currentPos
    offset
    最初为1),在2个单位后,在4个单位后,依此类推
  • 可能您正在尝试一种计算二次探头的快速方法。如果是这种情况,则偏移量不应增加2,而应乘以2。这可能是因为
    offset*=2
    ,但是因为您应该计算碰撞的数量,所以应该增加
    offset
  • 也许更简单的方法是:

    currentPos+=2*偏移量++-1;//快速实现二次分辨率的方法

  • 您的大小调整是可以的,因为它保证表至少有一半是空的,因此在执行插入时搜索可用条目是可以保证的


    祝你好运

    只是为了理解:你想说“双重哈希”吗?这就是问题所在