Pagini recente » Cod sursa (job #857407) | Cod sursa (job #321986) | Cod sursa (job #2349692) | Cod sursa (job #1529264) | Cod sursa (job #941303)
Cod sursa(job #941303)
/****** Berceanu Cristian 134 *******/
typedef unsigned int uint;
#define STOP 30
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <vector>
using namespace std;
class HashFunction
{
private:
uint a, b;
uint mod;
uint size;
public:
HashFunction(uint &);
void params();
uint function(int&);
uint function(uint&);
uint function(float&);
uint function(double&);
uint function(char&);
uint function(string&);
};
HashFunction::HashFunction(uint &n)
{
size = n;
params();
}
void HashFunction::params()
{
a = rand()%1000000+10;
b = rand()%1030000+10;
mod = size - size/10 + rand() % size/10;
}
uint HashFunction::function(char &value)
{
uint pos;
pos = ((a+b*value)%mod)%size;
return pos;
}
uint HashFunction::function(uint &value)
{
uint pos;
pos=((a+b*value)%mod)%size;
return pos;
}
uint HashFunction::function(int &value)
{
uint pos;
pos=((a+b*value)%mod)%size;
return pos;
}
uint HashFunction::function(float &value)
{
uint pos;
pos = (((long)a+(long)b*(long)value)%(long)mod)%(long)size;
return pos;
}
uint HashFunction::function(double &value)
{
uint pos;
pos = (((long)a+(long)b*(long)value)%(long)mod)%(long)size;
return pos;
}
uint HashFunction::function(string &value)
{
uint aux = 0;
for (uint i = 0;i<value.size();i++)
aux = (aux+a+b*value[i])%size;
return aux;
}
template<class type>
class BaseHash
{
public:
virtual bool operator+=(type &)=0;
virtual void operator-=(type &)=0;
virtual bool operator==(type &)=0;
virtual void init()=0;
bool solve();
};
template<class type>
bool BaseHash<type>::solve()
{
uint n, op, i, ok=0;
type x;
srand(time(NULL));
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>>x;
if(op==1)
ok = *this += x;
else
if(op==2)
*this -= x;
else
g<<(*this==x)<<"\n";
}
f.close();
g.close();
}
}
template<class type>
class ChainHash:public BaseHash<type>
{
uint size, nr;
type *v;
vector<uint> hash[666013];
HashFunction *func;
public:
ChainHash(uint);
~ChainHash();
bool operator+=(type &);
void operator-=(type &);
bool operator==(type &);
void init();
};
template<class type>
ChainHash<type>::ChainHash(uint x)
{
uint i;
size = x;
v=new type[size+1];
func = new HashFunction(size);
}
template<class type>
ChainHash<type>::~ChainHash()
{
delete[] v;
delete func;
}
template<class type>
bool ChainHash<type>::operator+=(type &value)
{
vector<uint>::iterator it;
uint pos, i;
pos= func->function(value);
v[++nr]=value;
for(it=hash[pos].begin();it!=hash[pos].end();it++)
if(v[*it]==value)
return true;
hash[pos].push_back(nr);
return true;
}
template<class type>
void ChainHash<type>::operator-=(type &value)
{
uint pos, i;
vector<uint>::iterator it;
pos = func->function(value);
for(it=hash[pos].begin();it!=hash[pos].end();it++)
if(v[*it]==value)
break;
if(it!=hash[pos].end())
{
*it=hash[pos].back();
hash[pos].pop_back();
}
}
template<class type>
bool ChainHash<type>::operator==(type &value)
{
uint pos, i;
vector<uint>::iterator it;
pos = func->function(value);
for(it=hash[pos].begin();it!=hash[pos].end();it++)
if(v[*it]==value)
return true;
return false;
}
template<class type>
void ChainHash<type>::init()
{
nr=0;
func->params();
}
template<class type>
class CuckooHash:public BaseHash<type>
{
uint size;
bool *v1, *v2;
type *hash1, *hash2;
HashFunction *f1, *f2;
public:
CuckooHash<type>(uint);
~CuckooHash<type>();
void init();
bool operator += (type &);
void operator -= (type &);
bool operator == (type &);
};
template<class type>
CuckooHash<type>::CuckooHash(uint n)
{
size = n;
v1 = new bool[size];
v2 = new bool[size];
hash1 = new type[size];
hash2 = new type[size];
f1 = new HashFunction(size);
f2 = new HashFunction(size);
}
template<class type>
CuckooHash<type>::~CuckooHash()
{
delete[] v1;
delete[] v2;
delete[] hash1;
delete[] hash2;
delete f1;
delete f2;
}
template<class type>
bool CuckooHash<type>::operator+=(type &value)
{
uint nr=0, pos1, pos2;
type aux;
pos1 = f1->function(value);
pos2 = f2->function(value);
if((hash1[pos1]==value && v1[pos1] ==1) || (hash2[pos2]==value && v2[pos2]==1))
return 1;
if(v1[pos1]==0)
{
hash1[pos1]=value;
v1[pos1]=1;
return true;
}
else
if(v2[pos2]==0)
{
hash2[pos2]=value;
v2[pos2]=1;
return true;
}
else
{
aux = value;
value = hash1[pos1];
hash1[pos1] = aux;
}
while(nr<STOP)
{
nr++;
pos2 = f2->function(value);
if(v2[pos2]==0)
{
hash2[pos2]=value;
v2[pos2]=1;
return 1;
}
else
{
pos1 = f1->function(hash2[pos2]);
aux=hash2[pos2];
hash2[pos2]=value;
value=hash1[pos1];
hash1[pos1]=aux;
}
}
return false;
}
template<class type>
void CuckooHash<type>::operator-=(type &value)
{
uint pos1, pos2;
pos1 = f1->function(value);
pos2 = f2->function(value);
if((hash1[pos1] == value) && v1[pos1] == 1)
v1[pos1]=0;
else
if(hash2[pos2] == value && v2[pos2] == 1)
v2[pos2] = 0;
}
template<class type>
bool CuckooHash<type>::operator==(type &value)
{
uint pos1, pos2;
pos1= f1->function(value);
pos2= f2->function(value);
if((hash1[pos1] == value && v1[pos1] == 1) || (hash2[pos2] == value && v2[pos2] == 1))
return 1;
else
return 0;
}
template<class type>
void CuckooHash<type>::init()
{
fill(v1,v1+size,0);
fill(v2,v2+size,0);
f1->params();
f2->params();
}
int main()
{
int x=1;
BaseHash <uint> *h;
switch(x)
{
case 1 : h = new ChainHash<uint>(1000001); break;
case 2 : h = new CuckooHash<uint>(1000001); break;
}
h->solve();
return 0;
}