Cod sursa(job #941243)

Utilizator BalcauIonutFMI-Balcau Ionut BalcauIonut Data 18 aprilie 2013 12:42:10
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 7.28 kb
// Balcau Ionut, gupa 134 - cukoo hash cu functii virtuale

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std; 



class baseHash
{
protected:
	uint *hash1,*hash2;
	uint a1,a2,b1,b2,size,m1,m2;

public:		 
	baseHash(uint n);
	virtual ~baseHash();
	void init();
	void setParams();
	virtual void solveHashuri()=0;
	virtual uint h1(uint &)=0;
	virtual uint h2(uint &)=0;
	virtual bool comp(uint, uint)=0;
	bool operator += (uint);
	void operator -= (uint);
	bool operator == (uint); 
};

baseHash::baseHash(uint n)    
{
	size=n;
	hash1 = new uint[size];
	hash2 = new uint[size];
}

baseHash::~baseHash()
{
	delete[] hash1;
	delete[] hash2;
}
void baseHash::setParams()
{
	a1 = rand() % size;
	b2 = rand() % size;
	a2 = rand() % size;
	b1 = rand() % size;
	m1 = size - size/10 + rand() % size/10;
	m2 = size - size/10 + rand() % size/10;
}


bool baseHash::operator+=(uint index)
{
	uint nr=0, i1, i2, aux; 
	i1 = h1(index);
	i2 = h2(index); 
	if( (comp(hash1[i1],index)) || ( comp(hash2[i2],index)) )
		return true; 
	if(hash1[i1]==0)
	{
		hash1[i1]=index;
		return true;
	}
	else
		if(hash2[i2]==0)
		{
			hash2[i2]=index;
			return true;
		}
		else
		{
			aux = index;
			index = hash1[i1];
			hash1[i1] = aux;
		} 
	while(nr<30)
	{
		nr++; 
		i2 = h2(index); 
		if(hash2[i2]==0)
		{
			hash2[i2]=index;
			return true;
		}
		else
		{
			i1 = h1(hash2[i2]);
			aux=hash2[i2];
			hash2[i2]=index;
			index=hash1[i1];
			hash1[i1]=aux;
		}
	}
	return false;
}


void baseHash::operator-=(uint index)
{
	uint i1, i2; 
	i1 = h1(index);
	i2 = h2(index); 
	if( comp(hash1[i1],index))
		hash1[i1]=0; 
	else
		if( comp(hash2[i2],index))
			hash2[i2] = 0;
	}


bool baseHash::operator==(uint index)
{
	uint i1, i2;
	i1 = h1(index);
	i2 = h2(index); 
	if( comp( hash1[i1], index ) || comp( hash2[i2], index ))
		return 1;
	else
		return 0;
}


void baseHash::init()
{
	fill(hash1,hash1+size,0);
	fill(hash2,hash2+size,0);
	setParams();
}


class intHash:public baseHash
{ 
	int *v; 
public: 
	intHash(uint size):baseHash(size)
	{
		v=new int[size+1];
	}
	~intHash(){ delete[] v;}
	void solveHashuri();
	uint h1(uint &);
	uint h2(uint &);
	bool comp(uint, uint);
};


void intHash::solveHashuri()
{
	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 intHash::h1(uint &index)
{
	uint poz;
	poz=((a1 + b1*v[index] ) % m1) % size;
	return poz;
}

uint intHash::h2(uint &index)
{
	uint poz;
	poz=((a2 + b2*v[index] ) % m2) % size;
	return poz;
}

bool intHash::comp(uint x, uint y)
{
	if(v[x]==v[y])
		return 1;
	else
		return 0;
} 


class uintHash:public baseHash
{ 
	uint *v; 
public: 
	uintHash(uint size):baseHash(size)
	{
		v=new uint[size+1];
	}
	~uintHash(){ delete[] v;}
	void solveHashuri();
	uint h1(uint &);
	uint h2(uint &);
	bool comp(uint, uint);
};


void uintHash::solveHashuri()
{
	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 uintHash::h1(uint &index)
{
	uint poz;
	poz=((a1 + b1*v[index] ) % m1) % size;
	return poz;
}

uint uintHash::h2(uint &index)
{
	uint poz;
	poz=((a2 + b2*v[index] ) % m2) % size;
	return poz;
}

bool uintHash::comp(uint x, uint y)
{
	if(v[x]==v[y])
		return 1;
	else
		return 0;
}

class stringHash: public baseHash
{
	string *v; 
public: 
	stringHash(uint size):baseHash(size)
	{
		v=new string[size+1];
	}
	~stringHash(){delete[] v;}
	void solveHashuri();
	uint h1(uint &);
	uint h2(uint &);
	bool comp(uint, uint);
};


void stringHash::solveHashuri()
{
	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 stringHash::h1(uint &index)
{
	uint aux = 0;
	for (uint i =0;i<v[index].size();i++)
		aux = (aux+a1 + b1*v[index][i])%size; 
	return aux;
}

uint stringHash::h2(uint &index)
{
	uint aux = 0;
	for (uint i =0;i<v[index].size();i++)
		aux = (aux+a2 + b2*v[index][i])%size; 
	return aux;
}

bool stringHash::comp(uint x, uint y)
{
	if(v[x]==v[y])
		return 1;
	else
		return 0;
}





class doubleHash:public baseHash
{ 
	double *v; 
public: 
	doubleHash(uint size):baseHash(size)
	{
		v=new double[size+1];
	}
	~doubleHash(){ delete[] v;}
	void solveHashuri();
	uint h1(uint &);
	uint h2(uint &);
	bool comp(uint, uint);
};


void doubleHash::solveHashuri()
{
	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 doubleHash::h1(uint &index)
{
	uint poz;
	while ((v[index]- int(v[index])) != 0)
	{
		v[index] *= 10;
		if (v[index] > size)
		{
			v[index] -= size;
		}
	}
	poz = (((uint)a1 + (uint)b1*(uint)v[index] ) % (uint)m1) % (uint)size;
	return poz;
}


uint doubleHash::h2(uint &index)
{
	int poz;
	while ((v[index] - int(v[index])) != 0)
	{
		v[index] *= 10;
		if (v[index] > size)
		{
			v[index] -= size;
		}
	}
	poz = (((uint)a2 + (uint)b2*(uint)v[index] ) % (uint)m2) % (uint)size;
	return poz;
}


bool doubleHash::comp(uint x, uint y)
{
	if(v[x]==v[y])
		return 1;
	else
		return 0;
}


class floatHash:public baseHash
{ 
	float *v; 
public: 
	floatHash(uint size):baseHash(size)
	{
		v=new float[size+1];
	}
	~floatHash(){ delete[] v;}
	void solveHashuri();
	uint h1(uint &);
	uint h2(uint &);
	bool comp(uint, uint);
};


void floatHash::solveHashuri()
{
	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 floatHash::h1(uint &index)
{
	uint poz;
	while ((v[index] - int(v[index])) != 0)
	{
		v[index] *= 10;
		if (v[index] > size)
		{
			v[index] -= size;
		}
	}
	poz = (((uint)a1 + (uint)b1*(uint)v[index] ) % (uint)m1) % (uint)size;
	return poz;
}


uint floatHash::h2(uint &index)
{
	int poz;
	while ((v[index] - int(v[index])) != 0)
	{
		v[index] *= 10;
		if (v[index] > size)
		{
			v[index] -= size;
		}
	}
	poz = (((uint)a2 + (uint)b2*(uint)v[index] ) % (uint)m2) % (uint)size;
	return poz;
}


bool floatHash::comp(uint x, uint y)
{
	if(v[x]==v[y])
		return 1;
	else
		return 0;
}



int main()
	{
	
	srand(time(NULL)); 
	baseHash *h; 
	// cin>>x;
	int x=2;
	switch(x){
	case 1 : h = new uintHash(1000001); break;		
	case 2 : h = new intHash(1000001); break;
	case 3 : h = new floatHash(1000001); break;
	case 4 : h = new doubleHash(1000001); break;
	case 5 : h = new stringHash(1000001);
	}
	
	h->solveHashuri(); 
	return 0;
}