Cod sursa(job #730093)

Utilizator dany123Florea Daniel dany123 Data 3 aprilie 2012 23:06:14
Problema Hashuri Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 4.75 kb
//hashing with open adressing
//fara var globale & clasa cu template, specializari pt: int, double, char si string
//h(x) = (h'(x) + r1 * i + r2 * i^2) % M
//Florea Daniel-Ciprian, gr. 135.
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<cstring>
using namespace std;

template <class T> //pt int si double
class Hash
{
	private:
		int r1,r2;
		static const int nmax=1000;
		bool *sters; //vector in care marchez elementele sterse
		T *v; //vectorul pt hashing
		int n;
		
	public:
		Hash (int nr) //constructor
		{
			n=nr;
			//vectorul
			v = new T [nmax]; //nu pot declara static un vector mare
			sters = new bool [nmax];
			memset (v,0,sizeof(v)*nmax);
			//initializam 2 valori random pt functia de hash
			srand(time(NULL));
			r1=rand()%nmax;
			r2=rand()%nmax;
		}
		~Hash () //destructor
		{
			delete[] v;
		}
		
		
		int has (int x, int i)//pt <int>
		{
			int rez=abs((x%nmax+r1*i+r2*i*i))%nmax;
			return rez;
		}
		
		int has (double x, int i)//pt <double>
		{	//h(x)=[ {knuth*x} * nmax ] + r1*i + r2*i*i
			double knuth=0.618033988749894L;
			int rez=abs( (int((knuth*x - int(knuth*x))*nmax)) %nmax+r1*i+r2*i*i )%nmax;
			return rez;
		}
		
		void inserare (T x)
		{
			int k=0;
			while (v[has(x,k)]!=0 && k<=nmax)
				k++;
			if (k>=n+1) 
			{
				cout<<"Vectorul este plin!"; 
				return;
			}
			v[has(x,k)]=x;
			sters[has(x,k)]=0;
			//cout<<"ASD"<<x;
		}
		
		void stergere (T x)
		{
			int k=0;
			while (v[has(x,k)]!=x && (v[has(x,k)]!=0 || sters[has(x,k)]==1) && k<=nmax) 
				k++;
			if (v[has(x,k)]==0) return;
			else if (k<=n) 
			{
				v[has(x,k)]=0;
				sters[has(x,k)]=1;
			}
		}
		
		bool cautare (T x)
		{
			int k=0;
			while (v[has(x,k)]!=x && (v[has(x,k)]!=0 || sters[has(x,k)]==1) && k<=nmax) 
				k++;
			if (k<=n && v[has(x,k)]==x) return 1;
			else return 0;
		}
		
		void afisare ()
		{
			cout<<"V= ";
			for (int i=0;i<nmax;++i)
				cout<<v[i]<<' ';
			cout<<endl;
		}
};

template <>
class Hash <string> //specializare pt string din cauza unor diferente la stergere si verificari
{
	private:
		int r1,r2;
		static const int nmax=1000;
		bool *sters; //vector in care marchez elementele sterse
		string *v; //vectorul pt hashing
		int n;
		
	public:
		Hash (int nr) //constructor
		{
			n=nr;
			//vectorul
			v = new string [nmax]; //nu pot declara static un vector mare
			sters = new bool [nmax];
			for (int i=0;i<nmax;++i)
			{
				v[i]=""; //memset-ul nu mi-a iesit pt stringuri, varianta asta este mai convenabila
				sters[i]=0;
			}
			//initializam 2 valori random pt functia de hash
			srand(time(NULL));
			r1=rand()%nmax;
			r2=rand()%nmax;
		}
		~Hash () //destructor
		{
			delete[] v;
		}
		
		
		int has (string x, int i)//pt <string>
		{
			unsigned int sum=0;
			int j;
			for (j=0;j+4<x.length();j+=4)
				sum+=x[j] + 128*x[j+1] + 128*128*x[j+2] + 128*128*128*x[j+3];
			while (j<=x.length())
			{
				sum+=x[j];
				++j;
			}
			int rez=(sum%nmax+r1*i+r2*i*i)%nmax;
			return rez;
		}
		
		void inserare (string x)
		{
			
			int k=0;
			while (v[has(x,k)]!="" && k<=nmax)
				k++;
			if (k>=n+1) 
			{
				cout<<"Vectorul este plin!"; 
				return;
			}
			v[has(x,k)]=x;
			sters[has(x,k)]=0;
		}
		
		void stergere (string x)
		{
			int k=0;
			while (v[has(x,k)]!=x && (v[has(x,k)]!="" || sters[has(x,k)]==1) && k<=nmax) 
				k++;
			if (v[has(x,k)]=="") return;
			else if (k<=n) 
			{
				v[has(x,k)]="";
				sters[has(x,k)]=1;
			}
		}
		
		bool cautare (string x)
		{
			int k=0;
			while (v[has(x,k)]!=x && (v[has(x,k)]!="" || sters[has(x,k)]==1) && k<=nmax) 
				k++;
			if (k<=n && v[has(x,k)]==x) return 1;
			else return 0;
		}
		
		void afisare ()
		{
			cout<<"V= ";
			for (int i=0;i<nmax;++i)
				cout<<v[i]<<' ';
			cout<<endl;
		}
};

template <>
class Hash <char> //specializare separata pt char pt ca e foarte simplu
{
	private:
		bool v[127];
	public:
		Hash (int n) //ignoram n-ul
		{
			for (int i=0;i<127;i++)
				v[i]=0;
		}
		
		void inserare (char x)
		{
			if (v[int(x)]==0)
				v[int(x)]=1;
		}
		
		void stergere (char x)
		{
			if (v[int(x)]==1)
				v[int(x)]=0;
		}
		
		bool cautare (char x)
		{
			if (v[int(x)]==1)
				return 1;
			else 
				return 0;
		}
		
		void afisare ()
		{
			cout<<"V= ";
			for (int i=0;i<127;++i)
				cout<<v[i]<<' ';
			cout<<endl;
		}
};

int main ()
{
	ifstream fin ("hashuri.in");
	ofstream fout ("hashuri.out");
	int op,n;
	
	fin>>n;
	Hash <int> h(n);
	int x;
	
	for (int i=1;i<=n;i++)
	{ 
		fin>>op>>x;
		/* PT STRING
		//getline(fin,x);
		//x=x.substr(1); //elimin spatiul
		*/
		if (op==1) { if (!h.cautare(x))  h.inserare(x); }
		else if (op==2) h.stergere(x);
		else if (op==3) fout<<h.cautare(x)<<'\n';
	}
	fin.close();
	fout.close();
	return 0;
}