用特定的转化规则,将字符串转成进制数用一定规则存放。
实现哈希查找
#include <stdio.h>
#include <ctype.h> //多谢citylove指正。
typedef struct
{
int nHashA;
int nHashB;
int bExists ;//是否冲突
}MPQHASHTABLE;
int nTableSize=40000000;
//crytTable[]里面保存的是HashString函数里面将会用到的一些数据,在prepareCryptTable
//函数里面初始化
unsigned long cryptTable[0x500];
//以下的函数生成一个长度为0x500(合10进制数:1280)的cryptTable[0x500]
void prepareCryptTable()
{
unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i;
for( index1 = 0; index1 < 0x100; index1++ )
{
for( index2 = index1, i = 0; i < 5; i++, index2 += 0x100 )
{
unsigned long temp1, temp2;
seed = (seed * 125 + 3) % 0x2AAAAB;
temp1 = (seed & 0xFFFF) << 0x10;
seed = (seed * 125 + 3) % 0x2AAAAB;
temp2 = (seed & 0xFFFF);
cryptTable[index2] = ( temp1 | temp2 );
}
}
}
//以下函数计算lpszFileName 字符串的hash值,其中dwHashType 为hash的类型,
//在下面GetHashTablePos函数里面调用本函数,其可以取的值为0、1、2;该函数
//返回lpszFileName 字符串的hash值;
unsigned long HashString( char *lpszFileName, unsigned long dwHashType )
{
unsigned char *key = (unsigned char *)lpszFileName;
unsigned long seed1 = 0x7FED7FED;
unsigned long seed2 = 0xEEEEEEEE;
int ch;
while( *key != 0 )
{
ch = toupper(*key++);
seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);
seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
}
return seed1;
}
void initHashTable(MPQHASHTABLE *lpTable,int size)
{
int i;
lpTable=(MPQHASHTABLE *)malloc(sizeof(MPQHASHTABLE)*size);
for( i=0;i<size;i++)
{
lpTable->bExists=0;//不冲突
lpTable->nHashA=0;
lpTable->nHashB=0;
}
}
void insertHashTable(MPQHASHTABLE *lpTable,char * lpszString)
{
const int HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;
int nHash = HashString(lpszString, HASH_OFFSET);
int nHashA = HashString(lpszString, HASH_A);
int nHashB = HashString(lpszString, HASH_B);
int nHashStart = nHash % nTableSize;
int nHashPos = nHashStart;
while ( lpTable[nHashPos].bExists!=1 )
{
/* 如果仅仅是判断在该表中时候存在这个字符串,就比较这两个hash值就可以了,不用对结构体中的字符串进行比较。这样会加快运行的速度?减少hash表占用的空间?这种
方法一般应用在什么场合?*/
nHashPos = (nHashPos + 1) % nTableSize;
}
lpTable[nHashPos].nHashA =nHashA;
lpTable[nHashPos].nHashB = nHashB ;
}
int GetHashTablePos( char *lpszString, MPQHASHTABLE *lpTable, int nTableSize )
{
const int HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;
int nHash = HashString(lpszString, HASH_OFFSET);
int nHashA = HashString(lpszString, HASH_A);
int nHashB = HashString(lpszString, HASH_B);
int nHashStart = nHash % nTableSize;
int nHashPos = nHashStart;
while ( lpTable[nHashPos].bExists )
{
/* 如果仅仅是判断在该表中时候存在这个字符串,就比较这两个hash值就可以了,不用对结构体中的字符串进行比较。这样会加快运行的速度?减少hash表占用的空间?这种
方法一般应用在什么场合?*/
if (lpTable[nHashPos].nHashA == nHashA
&& lpTable[nHashPos].nHashB == nHashB )
{
return nHashPos;
}
else
{
nHashPos = (nHashPos + 1) % nTableSize;
}
if (nHashPos == nHashStart) break;
}
return -1;
}
int main()
{
//char *A={"jttqzh","kwztsgxx","ilovestudy"};
MPQHASHTABLE *l;
initHashTable(l,nTableSize);
insertHashTable(l,"niceday");
insertHashTable(l,"studyday");
insertHashTable(l,"library");
printf("%d\nf",GetHashTablePos("niceday",l,nTableSize));
}