Cod sursa(job #941303)

Utilizator cristi_berceanuFMI - Cristi Berceanu cristi_berceanu Data 18 aprilie 2013 14:34:13
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 6.04 kb
/****** 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;
}