Cod sursa(job #941247)

Utilizator cristi_berceanuFMI - Cristi Berceanu cristi_berceanu Data 18 aprilie 2013 12:44:43
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 9.18 kb
/******* Berceanu Cristian 134 ******/
/* Cuckoo Hash cu functii virtuale */ 
#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:
	unsigned int *hash1, *hash2;
	unsigned int size; 
	unsigned int mod1, mod2;
	unsigned int a1, a2, b1, b2;

public:
 
	BaseHash(unsigned int n);
	virtual ~BaseHash();
	void init();
	void params();
	virtual void solve()=0;
	virtual unsigned int hashFunction1(unsigned int &)=0;
	virtual unsigned int hashFunction2(unsigned int &)=0;
	virtual bool compare(unsigned int, unsigned int)=0;
	bool operator += (unsigned int);
	void operator -= (unsigned int);
	bool operator == (unsigned int);
 
};
 
BaseHash::BaseHash(unsigned int n)  
{
	size=n;
	hash1 = new unsigned int[size];
	hash2 = new unsigned int[size];
}
 
BaseHash::~BaseHash()
{
	delete[] hash1;
	delete[] hash2;
}
 
void BaseHash::params()
{
	unsigned int pr[]={999983,999979,899981,900007,800011};
	a1 = rand()%size;
	a2 = rand()%size;
	b1 = rand()%size;
	b2 = rand()%size;
	mod1 = pr[rand ()%5];
	mod2 = pr[rand ()%5];
}
 
bool BaseHash::operator+=(unsigned int val)
{
	unsigned int 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<30)
		{
			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::operator-=(unsigned int val)
{
	unsigned int 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==(unsigned int val)
{
	unsigned int poz1, poz2;
	poz1 = hashFunction1(val);
	poz2 = hashFunction2(val);
	if(compare(hash1[poz1], val) || compare(hash2[poz2], val))
		return 1;
	else
		return 0;
}
 
void BaseHash::init()
{
	fill(hash1,hash1+size,0);
	fill(hash2,hash2+size,0);
	params();
}
   
class StringHash:public BaseHash
{
	string *v;
public:
	StringHash(unsigned int size):BaseHash(size)
	{
		v = new string[size+1];
	}
	~StringHash(){delete[] v;}
	void solve();
	unsigned int hashFunction1(unsigned int &);
	unsigned int hashFunction2(unsigned int &);
	bool compare(unsigned int, unsigned int);
 
};

void StringHash::solve()
{
	unsigned int 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();
		}
}
 
unsigned int StringHash::hashFunction1(unsigned int &val)
{
	unsigned int aux = 0;
	for (unsigned int i = 0;i < v[val].size(); i++)
		aux = (aux+a1 + b1*v[val][i])%size; 
	return aux;
}
 
unsigned int StringHash::hashFunction2(unsigned int &val)
{
	unsigned int aux = 0;
	for (unsigned int i = 0;i < v[val].size(); i++)
		aux = (aux+a2 + b2*v[val][i])%size; 
	return aux;
}
 
bool StringHash::compare(unsigned int x, unsigned int y)
{
	if(v[x] == v[y])
		return 1;
	else
		return 0;
}

class IntHash:public BaseHash
{
   
	int *v;  
public:
	IntHash(unsigned int size):BaseHash(size)
	{
		v = new int[size+1];
	}
	~IntHash(){ delete[] v;}
	void solve();
	unsigned int hashFunction1(unsigned int &);
	unsigned int hashFunction2(unsigned int &);
	bool compare(unsigned int, unsigned int);
};
void IntHash::solve()
{
unsigned int 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();
	}
}

unsigned int IntHash::hashFunction1(unsigned int &val)
{
	unsigned int poz; 
	poz=((a1 + b1*v[val])%mod1)%size;
	return poz;
}
 
unsigned int IntHash::hashFunction2(unsigned int &val)
{
	unsigned int poz;
	poz=((a2 + b2*v[val])%mod2)%size;
	return poz;
}
 
bool IntHash::compare(unsigned int x, unsigned int y)
{
	if(v[x]==v[y])
		return 1;
	else
		return 0;
}
 

class DoubleHash:public BaseHash
{
	double *v; 
public:
  
	DoubleHash(unsigned int size):BaseHash(size)
	{
		v = new double[size+1];
	}
	~DoubleHash(){ delete[] v;}
	void solve();
	unsigned int hashFunction1(unsigned int &);
	unsigned int hashFunction2(unsigned int &);
	bool compare(unsigned int, unsigned int);
 
};
 
void DoubleHash::solve()
{
	unsigned int 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();
		}
}
 
unsigned int DoubleHash::hashFunction1(unsigned int &val)
{
	unsigned int poz;
	while ((v[val]- int(v[val])) != 0)
	{
		v[val] *= 10;
		if (v[val] > size)
		{
			v[val] -= size;
		}
	}
	poz = (((unsigned int)a1 + (unsigned int)b1*(unsigned int)v[val])%(unsigned int)mod1)%(unsigned int)size;
	return poz;
}
 
unsigned int DoubleHash::hashFunction2(unsigned int &val)
{
	int poz;
	while ((v[val] - int(v[val])) != 0)
	{
		v[val] *= 10;
		if (v[val] > size)
		{
			v[val] -= size;
		}
	}
	poz = (((unsigned int)a2 + (unsigned int)b2*(unsigned int)v[val])%(unsigned int)mod2)%(unsigned int)size;
	return poz;
}
 
bool DoubleHash::compare(unsigned int x, unsigned int y)
{
	if(v[x]==v[y])
		return 1;
	else
		return 0;
}
 
class FloatHash:public BaseHash
{  
	float *v;
  
public:
  
	FloatHash(unsigned int size):BaseHash(size)
	{
		v = new float[size+1];
	}
	~FloatHash(){ delete[] v;}
	void solve();
	unsigned int hashFunction1(unsigned int &);
	unsigned int hashFunction2(unsigned int &);
	bool compare(unsigned int, unsigned int);
 
};
 
void FloatHash::solve()
{
	unsigned int 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();
		}
}
 
 
unsigned int FloatHash::hashFunction1(unsigned int &val)
{
unsigned int poz;
 
while ((v[val] - int(v[val])) != 0)
{
	v[val] *= 10;
	if (v[val] > size)
	{
		v[val] -= size;
	}
}
poz = (((unsigned int)a1 + (unsigned int)b1*(unsigned int)v[val])%(unsigned int)mod1)%(unsigned int)size;
return poz;
}
 
unsigned int FloatHash::hashFunction2(unsigned int &val)
{
int poz;
 
while ((v[val] - int(v[val])) != 0)
{
	v[val] *= 10;
	if (v[val] > size)
	{
		v[val] -= size;
	}
}
poz = (((unsigned int)a2 + (unsigned int)b2*(unsigned int)v[val])%(unsigned int)mod2)%(unsigned int)size;
return poz;
}
 
bool FloatHash::compare(unsigned int x, unsigned int y)
{
if(v[x]==v[y])
	return 1;
else
	return 0;
}
class UnsignedIntHash:public BaseHash
{  
	unsigned int *v; 
public:
  
	UnsignedIntHash(unsigned int size):BaseHash(size)
	{
		v = new unsigned int[size+1];
	}
	~UnsignedIntHash(){ delete[] v;}
	void solve();
	unsigned int hashFunction1(unsigned int &);
	unsigned int hashFunction2(unsigned int &);
	bool compare(unsigned int, unsigned int);
 
};
 
void UnsignedIntHash::solve()
{
	unsigned int 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();  
		}
}
 
unsigned int UnsignedIntHash::hashFunction1(unsigned int &val)
{
	unsigned int poz;
	poz=((a1 + b1*v[val])%mod1)%size;
	return poz;
}
 
unsigned int UnsignedIntHash::hashFunction2(unsigned int &val)
{
	unsigned int poz;
	poz=((a2 + b2*v[val])%mod2)%size;
	return poz;
}
 
bool UnsignedIntHash::compare(unsigned int x, unsigned int y)
{
	if(v[x]==v[y])
		return 1;
	else
		return 0;
}
 
 
int main()
{
	int x=2;
	srand(time(NULL));
	BaseHash *h;
	while(x<1||x>5)
	{
		cout<<"introduceti o valoare intre 1 si 5: ";
		cin>>x;
	}
	if(x==1)
		h = new UnsignedIntHash(1000000);
	else
		if(x==2)
			h = new IntHash(1000000);
		else
			if(x==3)
				h = new FloatHash(1000000);
			else
				if(x==4)
					h = new DoubleHash(1000000);
				else
					h = new StringHash(1000000);
				h->solve();
  
return 0;
}