开发者

hashkey collision when removing C++

开发者 https://www.devze.com 2022-12-08 08:12 出处:网络
To make the search foreach \"symbol\" i want to remove from my hashTable, i have chosen to generate the hashkey i inserted it at. However, the problem that Im seeing in my remove function is when I ne

To make the search foreach "symbol" i want to remove from my hashTable, i have chosen to generate the hashkey i inserted it at. However, the problem that Im seeing in my remove function is when I need to remove a symbol from where a collision was found it previously results in my while loop condition testing false where i do not want.

bool hashmap::get(char const * const symbol, stock& s) const
{
    int hash = this->hashStr( symbol );
    while ( hashTable[hash].m_symbol != NULL )
    {       // try to find a match for the stock associated with the symbol.
        if ( strcmp( hashTable[hash].m_symbol , symbol ) == 0 )
        {
            s = &hashTable[hash];
            return true;
        }
        ++hash %= maxSize;
    }
    return false;
}

bool hashmap::put(const stock& s, int& usedIndex, int& hashIndex, int& symbolHash)
{
    hashIndex = this->hashStr( s.m_symbol ); // Get remainder, Insert at that index.
    symbolHash = (int&)s.m_symbol;
    usedIndex = hashIndex;

    while ( hashTable[hashIndex].m_symbol != NULL ) // collision found
    {
        ++usedIndex %= maxSize; // if necessary wrap index around
        if ( hashTable[usedIndex].m_symbol == NULL )
        {
            hashTable[usedIndex] = s;
            return true;
        }
        else if ( strcmp( hashTable[usedIndex].m_symbol , s.m_symbol ) == 0 )
        {
            return false; // prevent duplicate entry
        }
    }
    hashTable[hashIndex] = s; // insert if no collision 
    return true;
}
// What if I need to remove an index i generate?
bool hashmap::remove(char const * const symbol)
{
    int hashVal = this->hashStr( symbol );
    while ( hashTable[hashVal].m_symbol != NULL )
    {
        if (开发者_StackOverflow strcmp( hashTable[hashVal].m_symbol, symbol ) == 0 )
        {
            stock temp = hashTable[hashVal]; // we cansave it
            hashTable[hashVal].m_symbol = NULL;
            return true;
        }
        ++hashVal %= maxSize; // wrap around if needed 
    }        // go to the next cell meaning their was a previous collision
    return false;
}

int hashmap::hashStr(char const * const str)
{   
    size_t length = strlen( str );
    int hash = 0;
    for ( unsigned i = 0; i < length; i++ )
    {
        hash = 31 * hash + str[i];
    }
    return hash % maxSize;
}

What would I need to do to remove a "symbol" from my hashTable from a previous collision? I am hoping it is not java's equation directly above.


It looks like you are implementing a hash table with open addressing, is that right? Deleting is a little tricky in that scheme. See http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf:

"Deletion of keys is problematic with open addressing: If there are two colliding keys x and y with h(x) = h(y), and key x is inserted before key y, and one wants to delete key x, this cannot simply be done by marking T[h(x)] as FREE, since then y would no longer be found. One possibility would be to mark T[h(x)] as DELETED (another special entry), which is skipped when searching for a key. A table place marked as DELETED may also be re-used for storing another key z that one wants to insert if one is sure that this key z is not already in the table (i.e., by reaching the end of the probe sequence for key z and not finding it). Such re-use complicates the insertion method. Moreover, places with DELETED keys fill the table."


What you need to do is create a dummy sentinel value that represents a "deleted" item. When you insert a new value into the table, you need to check to see if an element is NULL or "deleted". If a slot contains this sentinel "deleted" value or the slot is NULL, then the slot is a valid slot for insertion.

That said, if you are writing this code for production, you should consider using the boost::unordered_map, instead of rolling your own hash map implementation. If this is for schoolwork,... well, good luck.

0

精彩评论

暂无评论...
验证码 换一张
取 消