hash函数,实现从64bit生成32bit的hash,效率相对不错,但对时间没有进行测试,另外空间开销相对较大。
/*************************************************************************
> File Name: hash_table.cpp
> Author:wjy
> Mail: [email protected]
> Created Time: 二 7/ 8 09:54:52 2014
************************************************************************/
#include<iostream>
#include <time.h>
#include <string.h>
#include <ctime>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
unsigned long matrix[]={
694164548, 3789149486, 3807463199, 2684797435, 2359943013, 2231240996, 2135863124, 1211164704, 2302089482, 4105647604, 3076642034, 72161852, 59560020, 611878035, 2814490697, 3915797072, 1219075273, 3978906545, 193953705, 4132630722, 2627050652, 1989142569, 2745032496, 735086709, 3485798578, 1637027010, 2467907528, 3110718702, 1201254602, 3737777921, 796676896, 2349326933, 2449810837, 3910433321, 3550767862, 1644342526, 1438602584, 2179832898, 3868189175, 1814084994, 615833333, 2031832363, 3130167043, 4200349959, 1930419194, 3787258680, 3369981751, 3329843958, 3446569769, 3858118227, 163055231, 1009035244, 422846498, 1011763997, 533633029, 2557610330, 4221463260, 95017657, 88369066, 3227540105, 3815919250, 2234633741, 1819183943, 556442040
};
void changeToArray(unsigned long long input , int *array,int len) {
len = 64;
for(int i=0;i<len;i++) {
if(((input>>i)&0x1) == 1) {
array[i] = 1;
} else {
array[i] = 0;
}
}
}
int Matrix[32][64];
void changeToMatrix(){
for(int i=0;i<32;i++)
for(int j=0;j<64;j++) {
if(((matrix[i]>>j)&0x1)==1) {
Matrix[i][j] = 1;
} else {
Matrix[i][j] = 0;
}
}
}
unsigned int MatrixHash(unsigned long long input) {
int tmp[64];
changeToArray(input,tmp,64);
// for(int i=0;i<64;i++)
// cout<<tmp[i];
unsigned int res=0;
for(int i=0;i<64;i++) {
if(tmp[i]==1) {
res = res ^ matrix[i];
}
}
return res;
}
/* End Of AP Hash Function */
const int NUM = 1000003; //10000019
struct HashNode {
unsigned long long key;
unsigned int value;
HashNode *next;
bool flag;
HashNode(){
flag=false;
next = NULL;
key=0;
value = 0;
}
HashNode(unsigned long long key,int value):key(key),value(value){
next = NULL;
flag = false;
}
};
HashNode hnode[NUM];
/*unsigned int hashvalue(char *str) {
register unsigned int h;
register unsigned char *p;
for(h=0,p=(unsigned char *)str;*p;p++) {
h = (h<<5) - h + (*p); // h = 31 * h + *p;
}
return h;
}*/
bool isContainsKey(unsigned long long key) {
char tmp[65];
// itoa(key,tmp,10);
// sprintf(tmp,"%d",key);
// int len = strlen(tmp);
unsigned int hashcode = MatrixHash(key)%NUM;
if(hnode[hashcode].flag==false) {
return false;
} else {
HashNode *p = &hnode[hashcode];
while(p!=NULL) {
if(p->key==key) {
return true;
}
p = p -> next;
}
}
return false;
}
void put(unsigned long long key,int value) {
// char tmp[65];
// itoa(key,tmp,10);
// sprintf(tmp,"%d",key);
// int len=strlen(tmp);
unsigned int hashcode = MatrixHash(key)%NUM;
if(hnode[hashcode].flag==false) {
hnode[hashcode].flag = true;
hnode[hashcode].key = key;
hnode[hashcode].value = value;
} else if(!isContainsKey(key)){
HashNode *p = new HashNode(key,value);
p->flag = true;
p->next = hnode[hashcode].next;
hnode[hashcode].next = p;
} else {
HashNode *p = &hnode[hashcode];
while(p!=NULL) {
if(p->key==key) {
p->value = value;
break;
}
p = p -> next;
}
}
}
int get(unsigned long long key){
// char tmp[65];
// itoa(key,tmp,10);
// sprintf(tmp,"%llu",key);
// int len = strlen(tmp);
unsigned int hashcode = MatrixHash(key)%NUM;
if(isContainsKey(key)==false){
// alert("the key not exists");
return -1;
} else {
HashNode *p = &hnode[hashcode];
while(p!=NULL) {
if(p->key==key) {
return p->value;
}
p = p -> next;
}
}
return -1;
}
unsigned long long strToUll(char * key,int len) {
unsigned long long res = 0;
for(int i=len-1;i>=0;i--) {
res = res * 10 + (key[i]-‘0‘);
}
return res;
}
int main(){
FILE *fp = fopen("data.txt","r");
if(fp==NULL) {
cout<<"end"<<endl;
exit(-1);
}
char key[65];
while(!feof(fp)) {
fscanf(fp,"%s",key);
int len = strlen(key);
put(strToUll(key,len),1);
}
fclose(fp);
fp = fopen("matrixhash","w");
FILE* fp2 = fopen("count_matrixhash","w");
int sum = 0;
for(int i=0;i<NUM;i++) {
int count = 0;
HashNode *p = &hnode[i];
while(p!=NULL&&p->flag!=false) {
if(p->flag!=false) {
count++;
if(p->key!=0)
fprintf(fp,"%llu->%d\n",p->key,p->value);
}
p=p->next;
}
if(count>0) sum+=1;
if(count>=1) {
// fprintf(fp2,"%d th node has %d collision\n",i,count);
fprintf(fp2,"%d\n",count);
}
}
cout<<"matrixhash"<<"\t"<<count<<"\t"<<NUM<<endl;
fclose(fp2);
fclose(fp);
return 0;
}
MatrixHash 实现和测试(二),布布扣,bubuko.com