设置整数哈希?

时间:2016-04-28 05:20:32

标签: c++

我必须为一组int创建一个哈希。我需要使用的哈希函数是:

f(x) = k * x % TableSize.

我知道我肯定需要4个循环,它们的设置如下:

Outer loop - TableSize = 10 to 1000
Middle loop - k = 1 to 500
Inner loop - create a table, and set it to -1
Inner inner loop - step through 10 #s loc = f(num)

问题是,虽然我知道如何设置外部和中间循环,但我对最后两个循环感到困惑。

虽然我知道如何设置字符串的哈希表,但我不知道如何为整数做这个(因为我听说设置有点不同)。另外,根据要求,我是在内循环中创建表,还是只调用不同的函数?

这是我在.h文件中的所有内容。

#pragma once
#include <iostream>
#include <string>

using namespace std;

class intHash{

public:
intHash(int tableSize);
~intHash();

void someStuff(){
    for (int TableSize = 10; TableSize < 1000; TableSize++){ 
        for (int k = 1; k < 500; k++){
            for (){
                intHash(-1);
                for (){

                }
            }
        }
    }
}


private:
string *hashTable;
};

1 个答案:

答案 0 :(得分:0)

好的,这样做很有趣。当然,你按原样转动它,你将因为作弊而失败。

此哈希使用布尔值来确定哈希是否正在使用。它通过逐步踩到桌子来处理碰撞,直到找到一个开口。另一种方法是在每个位置设置一个列表,并使用比较来遍历列表。要么有效。

请注意,使用其他类型所需要做的就是更改HashValueTableEntry值的类型。该类型需要支持一些算法按原样使用,但我希望对更复杂的类型使用新的哈希函数。

无论如何,这给你一个哈希函数的工作思路。

#include <iostream>

class intHash
{
public:
    typedef int HashValueType;

    intHash(int tableSize)
    {
        m_tableSize = tableSize;
        m_hashTable = new HashValueTableEntry[tableSize];
    }

    ~intHash()
    {
        delete[] m_hashTable;
    }

    HashValueType add(int value)
    {
        int hashValue = hash(value);
        m_hashTable[hashValue].inUse = true;
        m_hashTable[hashValue].value = value;

        return hashValue;
    }

    bool get(HashValueType hashValue, int *value)
    {
        if(m_hashTable[hashValue].inUse)
        {
            *value = m_hashTable[hashValue].value;
            return true;
        }

        return false;
    }

    void remove(HashValueType hashvalue)
    {
        m_hashTable[hashvalue].inUse = false;
    }

private:
    struct HashValueTableEntry
    {
        HashValueTableEntry() : value(0), inUse(false) {}
        int value;
        bool inUse;
    };

    int hash(int value)
    {
        static const int k = 7;
        int currentHash = (value * k ) % m_tableSize;

        int overflowCounter = 0;

        // Collision resolution
        while(m_hashTable[currentHash].inUse == true && 
              m_hashTable[currentHash].value != value)
        {
            currentHash++;
            if(overflowCounter++ == m_tableSize)
            {
                // assert, end the world, error whatever.
                // At this point though, currentHash is garbage and should be handled.
                break;
            }
        }

        return currentHash;
    }

    HashValueTableEntry *m_hashTable;
    int m_tableSize;
};

int main(void)
{
    intHash hash(100);
    int hashValues[100];

    for(int i=0; i<10; i++)
    {
        hashValues[i] = hash.add(i);

        // Purposely setup hash collisions to show that it is handled.
        hashValues[i+10] = hash.add(i+100);
    }

    for(int i=0; i<20; i++)
    {
        int tableValue = 0;
        hash.get(hashValues[i], &tableValue);
        std::cout << "Hash is " << hashValues[i] << " value is " << tableValue << std::endl;
    }

    return 0;
}