Pagini recente » Cod sursa (job #2890035) | Cod sursa (job #1916554) | Cod sursa (job #206822) | Cod sursa (job #2743191) | Cod sursa (job #941326)
Cod sursa(job #941326)
/****** Berceanu Cristian 134 *******/
/* Cuckoo Hash cu functii virtuale */
typedef unsigned int uint;
#define STOP 30
#include <stdio.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <cstdio>
using namespace std;
class BaseHash
{
protected:
uint *hash1, *hash2;
uint hash_size;
uint mod1, mod2;
uint a1, a2, b1, b2;
public:
BaseHash(uint n);
virtual ~BaseHash();
void init();
void params();
virtual void solve()=0;
virtual uint hashFunction1(uint &)=0;
virtual uint hashFunction2(uint &)=0;
virtual bool compare(uint, uint)=0;
bool operator == (uint);
bool operator += (uint);
void operator -= (uint);
};
BaseHash::BaseHash(uint n)
{
hash_size=n;
hash1 = new uint[hash_size];
hash2 = new uint[hash_size];
}
BaseHash::~BaseHash()
{
delete[] hash1;
delete[] hash2;
}
void BaseHash::params()
{
a1 = rand() % hash_size;
b2 = rand() % hash_size;
a2 = rand() % hash_size;
b1 = rand() % hash_size;
mod1 = hash_size - hash_size/10 + rand() % hash_size/10;
mod2 = hash_size - hash_size/10 + rand() % hash_size/10;
}
bool BaseHash::operator==(uint val)
{
uint poz1, poz2;
poz1 = hashFunction1(val);
poz2 = hashFunction2(val);
if(compare(hash1[poz1], val) || compare(hash2[poz2], val))
return 1;
else
return 0;
}
void BaseHash::operator-=(uint val)
{
uint poz1, poz2;
poz1 = hashFunction1(val);
poz2 = hashFunction2(val);
if(compare(hash1[poz1],val))
hash1[poz1]=0;
else
if(compare(hash2[poz2],val))
hash2[poz2] = 0;
}
bool BaseHash::operator+=(uint val)
{
uint nr=0, poz1, poz2, aux;
poz1 = hashFunction1(val);
poz2 = hashFunction2(val);
if((compare(hash1[poz1],val)) || (compare(hash2[poz2],val)))
return true;
if(hash1[poz1]==0)
{
hash1[poz1]=val;
return true;
}
else
if(hash2[poz2]==0)
{
hash2[poz2]=val;
return true;
}
else
{
aux = val;
val = hash1[poz1];
hash1[poz1] = aux;
}
while(nr<STOP)
{
nr++;
poz2 = hashFunction2(val);
if(hash2[poz2]==0)
{
hash2[poz2]=val;
return true;
}
else
{
poz1 = hashFunction1(hash2[poz2]);
aux=hash2[poz2];
hash2[poz2]=val;
val=hash1[poz1];
hash1[poz1]=aux;
}
}
return false;
}
void BaseHash::init()
{
fill(hash1,hash1+hash_size,0);
fill(hash2,hash2+hash_size,0);
params();
}
class IntHash:public BaseHash
{
int *v;
public:
IntHash(uint hash_size):BaseHash(hash_size)
{
v = new int[hash_size+1];
}
~IntHash(){ delete[] v;}
void solve();
uint hashFunction1(uint &);
uint hashFunction2(uint &);
bool compare(uint, uint);
};
uint IntHash::hashFunction1(uint &val)
{
uint poz;
poz=((a1 + b1*v[val])%mod1)%hash_size;
return poz;
}
uint IntHash::hashFunction2(uint &val)
{
uint poz;
poz=((a2 + b2*v[val])%mod2)%hash_size;
return poz;
}
void IntHash::solve()
{
uint n, op, i, ok=0;
while(ok==0)
{
init();
ifstream f("hashuri.in");
ofstream g("hashuri.out");
f>>n;
ok=1;
for(i=1;i<=n&&ok;i++)
{
f>>op>>v[i];
if(op==1)
ok = *this += i;
else
if(op==2)
*this -= i;
else
g<<(*this==i)<<"\n";
}
f.close();
g.close();
}
}
bool IntHash::compare(uint x, uint y)
{
if(v[x]==v[y])
return 1;
else
return 0;
}
class StringHash:public BaseHash
{
string *v;
public:
StringHash(uint hash_size):BaseHash(hash_size)
{
v = new string[hash_size+1];
}
~StringHash(){delete[] v;}
void solve();
uint hashFunction1(uint &);
uint hashFunction2(uint &);
bool compare(uint, uint);
};
uint StringHash::hashFunction1(uint &val)
{
uint aux = 0;
for (uint i = 0;i < v[val].size(); i++)
aux = (aux+a1 + b1*v[val][i])%hash_size;
return aux;
}
uint StringHash::hashFunction2(uint &val)
{
uint aux = 0;
for (uint i = 0;i < v[val].size(); i++)
aux = (aux+a2 + b2*v[val][i])%hash_size;
return aux;
}
void StringHash::solve()
{
uint n, op, i, ok=0;
while(ok==0)
{
init();
ifstream f("hashuri.in");
ofstream g("hashuri.out");
f>>n;
ok=1;
for(i=1;i<=n&&ok;i++)
{
f>>op>>v[i];
if(op==1)
ok = *this += i;
else
if(op==2)
*this -= i;
else
g<<(*this==i)<<"\n";
}
f.close();
g.close();
}
}
bool StringHash::compare(uint x, uint y)
{
if(v[x] == v[y])
return 1;
else
return 0;
}
class DoubleHash:public BaseHash
{
double *v;
public:
DoubleHash(uint hash_size):BaseHash(hash_size)
{
v = new double[hash_size+1];
}
~DoubleHash(){ delete[] v;}
void solve();
uint hashFunction1(uint &);
uint hashFunction2(uint &);
bool compare(uint, uint);
};
class FloatHash:public BaseHash
{
float *v;
public:
FloatHash(uint hash_size):BaseHash(hash_size)
{
v = new float[hash_size+1];
}
~FloatHash(){ delete[] v;}
void solve();
uint hashFunction1(uint &);
uint hashFunction2(uint &);
bool compare(uint, uint);
};
uint FloatHash::hashFunction1(uint &val)
{
uint poz;
while ((v[val]-int(v[val]))!=0)
{
v[val] *= 10;
if (v[val] > hash_size)
{
v[val] -= hash_size;
}
}
poz = (((uint)a1 + (uint)b1*(uint)v[val])%(uint)mod1)%(uint)hash_size;
return poz;
}
uint FloatHash::hashFunction2(uint &val)
{
int poz;
while ((v[val] - int(v[val])) != 0)
{
v[val] *= 10;
if (v[val] > hash_size)
{
v[val] -= hash_size;
}
}
poz = (((uint)a2 + (uint)b2*(uint)v[val])%(uint)mod2)%(uint)hash_size;
return poz;
}
void FloatHash::solve()
{
uint n, op, i, ok=0;
while(ok==0)
{
init();
ifstream f("hashuri.in");
ofstream g("hashuri.out");
f>>n;
ok=1;
for(i=1;i<=n&&ok;i++)
{
f>>op>>v[i];
if(op==1)
ok = *this += i;
else
if(op==2)
*this -= i;
else
g<<(*this==i)<<"\n";
}
f.close();
g.close();
}
}
bool FloatHash::compare(uint x, uint y)
{
if(v[x]==v[y])
return 1;
else
return 0;
}
uint DoubleHash::hashFunction1(uint &val)
{
uint poz;
while ((v[val]-int(v[val])) != 0)
{
v[val] *= 10;
if (v[val]>hash_size)
{
v[val] -= hash_size;
}
}
poz = (((uint)a1 + (uint)b1*(uint)v[val])%(uint)mod1)%(uint)hash_size;
return poz;
}
uint DoubleHash::hashFunction2(uint &val)
{
int poz;
while ((v[val] - int(v[val])) != 0)
{
v[val] *= 10;
if (v[val]>hash_size)
{
v[val] -= hash_size;
}
}
poz = (((uint)a2 + (uint)b2*(uint)v[val])%(uint)mod2)%(uint)hash_size;
return poz;
}
void DoubleHash::solve()
{
uint n, op, i, ok=0;
while(ok==0)
{
init();
ifstream f("hashuri.in");
ofstream g("hashuri.out");
f>>n;
ok=1;
for(i=1;i<=n&&ok;i++)
{
f>>op>>v[i];
if(op==1)
ok = *this += i;
else
if(op==2)
*this -= i;
else
g<<(*this==i)<<"\n";
}
f.close();
g.close();
}
}
bool DoubleHash::compare(uint x, uint y)
{
if(v[x]==v[y])
return 1;
else
return 0;
}
class UnsignedIntHash:public BaseHash
{
uint *v;
public:
UnsignedIntHash(uint hash_size):BaseHash(hash_size)
{
v = new uint[hash_size+1];
}
~UnsignedIntHash(){ delete[] v;}
void solve();
uint hashFunction1(uint &);
uint hashFunction2(uint &);
bool compare(uint, uint);
};
void UnsignedIntHash::solve()
{
uint n, op, i, ok=0;
while(ok==0)
{
init();
ifstream f("hashuri.in");
ofstream g("hashuri.out");
f>>n;
ok=1;
for(i=1;i<=n&&ok;i++)
{
f>>op>>v[i];
if(op==1)
ok = *this += i;
else
if(op==2)
*this -= i;
else
g<<(*this==i)<<"\n";
}
f.close();
g.close();
}
}
uint UnsignedIntHash::hashFunction1(uint &val)
{
uint poz;
poz=((a1 + b1*v[val])%mod1)%hash_size;
return poz;
}
uint UnsignedIntHash::hashFunction2(uint &val)
{
uint poz;
poz=((a2 + b2*v[val])%mod2)%hash_size;
return poz;
}
bool UnsignedIntHash::compare(uint x, uint y)
{
if(v[x]==v[y])
return 1;
else
return 0;
}
int main()
{
srand(time(NULL));
BaseHash *h;
int x=1;
switch(x)
{
case 1 : h = new IntHash(1000001); break;
case 2 : h = new UnsignedIntHash(1000001); break;
case 3 : h = new FloatHash(1000001); break;
case 4 : h = new DoubleHash(1000001); break;
case 5 : h = new StringHash(1000001);
}
h->solve();
return 0;
}