我必须为一组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;
};
答案 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;
}