// 计算完美HASH
#include "stdafx.h"
#include <windows.h>
#include <algorithm>
#include <iostream>
using namespace std;
// HASH函数为 data%HashSize
// 返回完美HASH的尺寸
// 失败返回0
unsigned int GetPerfectHash(const unsigned int* pData, size_t iNum, size_t iMaxHashSize);
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int data[] = {204, 83, 111, 103, 46, 115, 82, 145};
size_t nNum = sizeof(data)/sizeof(data[0]);
size_t iHashSize = GetPerfectHash(data, nNum, nNum*3);
cout << "// HashSize = " << iHashSize << endl;
if(iHashSize != 0)
{
for(size_t i=0; i<nNum; ++i)
{
cout << "// hash(" << data[i] << ") = " << data[i]%iHashSize << endl;
}
}
return 0;
}
unsigned int GetPerfectHash(const unsigned int* pData, size_t iNum, size_t iMaxSize)
{
if(pData == 0)
return 0;
if(iNum <= 1)
return iNum;
if(iMaxSize < iNum)
iMaxSize = iNum;
bool* pConflict = new bool[iMaxSize];
for(size_t nHashSize = iNum; nHashSize<=iMaxSize; ++nHashSize)
{
fill(pConflict, pConflict+nHashSize, false);
bool bFindPerfect = true;
for(size_t i=0; i<iNum; ++i)
{
unsigned int iHash = pData[i] % nHashSize;
if(pConflict[iHash])
{
bFindPerfect = false;
break;
}
pConflict[iHash] = true;
}
if(bFindPerfect)
{
delete[] pConflict;
return nHashSize;
}
}
delete[] pConflict;
return 0;
}
// 运行结果:
// HashSize = 22
// hash(204) = 6
// hash(83) = 17
// hash(111) = 1
// hash(103) = 15
// hash(46) = 2
// hash(115) = 5
// hash(82) = 16
// hash(145) = 13