#include<iostream>
#include<fstream>
#include<memory>
#include<math.h>
typedef unsigned __int64 Uint;
using namespace std;
struct Hash_elem{ //hash_table的元素
Uint hash_key;
int hash_value;
};
struct Hash_table
{
Hash_elem *table;
int count;
int sizeindex;
};
unsigned int size_array[]={257,503,1009,2027,4073,8039,9973,20011,29989,41011,50587,62927,73877,84463,99991};//递增容量表
int hash_size=size_array[0];
int col;
int bits;
Uint pre;
Uint cbtoc(char* ch){
Uint v=0;
for(int i=0;i<bits;i++)
{
if(ch[i]=='1')
v+=(1<<(bits-1-i));
}
return v;
}
unsigned int hash(Uint &v) //哈希函数
{
return v%hash_size;
}
void collision(unsigned int &p,int d) //冲突处理,线性探测增量
{
p=(p+d)%hash_size;
}
void hash_init(Hash_table &H)//建立hash表
{
col=0;
H.count=0;
H.table=(Hash_elem*)malloc(sizeof(Hash_elem)*hash_size);
if(!H.table){
cout<<"overflow";
exit(0);}
for(int i=0;i<hash_size;i++)
H.table[i].hash_value=0;
}
void hash_search(Hash_table H,Uint Key,unsigned int &p)
{
col=0;
p=hash(Key);
while(H.table[p].hash_value!=0 && Key!=H.table[p].hash_key)
{
col++;//冲突数+1
if(col<hash_size)
collision(p,col);
else
break;
}
/* if(Key==H.table[p].hash_key)
return 1;//key值相同
else
return 0;//可用的空hash值*/
}
void hash_insert(Hash_table& H,unsigned int& p,Uint& v)
{
H.table[p].hash_value++;
H.table[p].hash_key=v;
H.count++;
}
void get_bits();
void hash_resize(Hash_table& H)//自动扩充容量
{
cout<<"resize!!!"<<endl;
H.sizeindex++;
hash_size=size_array[H.sizeindex];
}
void get_bits(Hash_table &H,ifstream &inf){
unsigned int p;
Uint v;
char c;
hash_init(H);
H.sizeindex=0;
while((c = inf.get())!= EOF) {
if(c=='/n') //到达换行符,吃掉
continue;
char ch[512];
inf.putback(c);
inf.get(ch,bits+1);
if(strlen(ch)<bits) //尾数不足bits位,剔除
continue;
v=cbtoc(ch);
cout<<hash(v)<<' ';
printf("%I64u/n",v);
hash_search(H,v,p);
if(col>hash_size/2)
{
free(H.table);//释放内存
inf.seekg(0, ios_base::beg);//回到开头
hash_resize(H);
hash_init(H);
continue;
}
else
hash_insert(H,p,v);
}
}
void get_bits2(Hash_table &H,ifstream &inf){
unsigned int p;
Uint v,v1;
char c;
hash_init(H);
H.sizeindex=0;
while((c = inf.get())!= EOF) {
if(c=='/n') //到达换行符,吃掉
continue;
char ch[512];
inf.putback(c);
inf.get(ch,bits+1);
if(strlen(ch)<bits) //尾数不足bits位,剔除
continue;
v=cbtoc(ch);
v1=v+(pre<<bits);
pre=v;
hash_search(H,v1,p);
if(col>hash_size/2)
{
free(H.table);//释放内存
inf.seekg(0, ios_base::beg);//回到开头
hash_resize(H);
hash_init(H);
continue;
}
else
hash_insert(H,p,v1);
}
}
int main(){
double p_si;
double si_h;
double si_h0=0;
double si_h1=0;
Hash_table H;
bool flag=0;
cout<<"please input bits:"<<endl;
cin>>bits;
char chf[512];//第一个元素
ifstream fin("D:/in.txt");
fin.get(chf,bits+1);//第一个元素,特殊处理。。
while(strlen(chf)<bits)
{
fin.get();
fin.get(chf,bits+1);
}
Uint fv=cbtoc(chf);
pre=fv;
fin.seekg(0, ios_base::beg);
get_bits(H,fin);//读入hash table
if(H.table[hash(fv)].hash_value==1)
{
H.table[hash(fv)].hash_value=0;
flag=1;//剔除第一个元素标志
}
unsigned int hspre=hash_size;
hash_size=size_array[0];
fin.clear();
fin.seekg(0, ios_base::beg);
fin.get(chf,bits+1); //吃掉第一个
while(strlen(chf)<bits)
{
fin.get();
fin.get(chf,bits+1);
}
Uint judge=(1<<bits)-1;
Hash_table H1;
get_bits2(H1,fin);
for(int i=0;i<hspre;i++)
if(H.table[i].hash_value)
{
double temp=0;
for(int j=0;j<hash_size;j++)
if((H.table[i].hash_key & H1.table[j].hash_key)==judge)
{
double p_sji=double(H1.table[j].hash_value)/double(H.table[i].hash_value);
temp+=(p_sji*(log(p_sji)/log(2)));
}
si_h1+=(p_si*temp);
int temp1=H.table[i].hash_value;
// cout<<hex<<H.table[i].hash_key<<dec<<'/t';
printf("%I64u/t",H.table[i].hash_key);
p_si=double(temp1)/double(H.count);
si_h=log(temp1)/log(2);
cout<<"H="<<si_h<<'/t'<<endl;//输出H
si_h0+=(p_si*(log(p_si)/log(2)));
}
cout<<"H0="<<-si_h0<<endl;
cout<<"H1="<<-si_h1<<endl;
return 0;
}