Cod sursa(job #941326)

Utilizator cristi_berceanuFMI - Cristi Berceanu cristi_berceanu Data 18 aprilie 2013 15:04:12
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 8.42 kb
/****** 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;
}