Cod sursa(job #719622)

Utilizator mr.johnFMI - Laceanu Ionut-Adrian mr.john Data 21 martie 2012 22:04:46
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
//Laceanu Ionut-Adrian
//Double Hashing cu Template
//F.M.I., gr.135

#include <stdio.h>
#include <fstream>
#define MOD 1000001
#define MOD2 1000002

using namespace std;


template <class MyType> //clasa functioneaza pentru stringuri si pentru orice tip de date
class hash{		// care poate fi convertit la int prin cast. Deasemenea, MyType trebuie
	MyType T[MOD]; // sa suporte testul de egalitate (==)
	char sters[MOD];
	char ocupat[MOD];

	public:
	unsigned int h(MyType,int); // functia h este private, deoarece va fi apelata doar de metodele
	                            // insert, query si remove
		
	hash(){
		for (int i=0;i<MOD;i++){
			T[i]=0;
			sters[i]=0;
			ocupat[i]=0;
		}
	}
	int query(MyType x){
		int t;
		for(int i=0;;i++){
			t=h(x,i);                   //self-explanatory
			if (ocupat[t]==0) return 0;
			if (T[t]==x && !sters[t]) return 1;
		}
		return 0;
	}
	unsigned int insert(MyType x){
		unsigned int i,temp,j;
		for (i=0;temp=h(x,i), ocupat[temp]&&(T[temp]!=x||sters[temp])&&(i<MOD2); i++); //parcurgem tabela pana
		if (T[temp]==x && ocupat[temp]) return -1;      //gasim elementul sau o pozitie
		for (j=0;ocupat[h(x,j)]&&!sters[h(x,j)];j++);   //libera, unde il vom insera.
		T[h(x,j)]=x;
		sters[h(x,j)]=0;
		ocupat[h(x,j)]=1;
		return h(x,j);		//va returna pozitia in care s-a inserat sau, in caz de esec, -1
	}
	unsigned int remove(MyType x){
		unsigned int temp;
		for(int i=0;;i++){        //parcurgem tabela pana cand fie gasim elementul, pe care il inlocuim cu -1
			temp=h(x,i);             //fie gasim o pozitie neocupata, ceea ce inseamna ca elementul nu se afla in tabela. 
			if (!ocupat[temp]) return -1;
			if (T[temp]==x && !sters[temp]){
				sters[temp]=1;
				return temp;      //returneaza pozitia pe care se afla elementul sau, in caz de esec, -1
			}
		}
	}
};


template<class MyType>
unsigned int hash<MyType>::h(MyType x, int i){	//functia de hash valabila pentru orice tip de date
		return (((x%MOD)+i*(1+x%MOD2))%MOD); // care poate fi convertit la int prin operatorul cast
}

template<> 
unsigned int hash<char *>::h(char *str, int i){ 
	unsigned int x = 5381;	// aceasta functie este specializata pentru stringuri
	int c;
	while ((c = *str++))
		x = ((x << 5) + x) + c; 
	return (((x%MOD)+i*(1+x%MOD2))%MOD);
}

int main(){
	int n;
	hash<unsigned int> has;
	ifstream fin("hashuri.in");
	freopen("hashuri.out","w",stdout);
	unsigned int op,nr;
	float x;
	char c[30];
	fin>>n;
//	printf("%d\n",has.h(33968011,12542));
	for (register int i=1;i<=n;i++){
		fin>>op>>nr;
//		fin.getline(c,300);
		if (op==1){ has.insert(nr); continue;}
		if (op==2){ has.remove(nr); continue;}
		if (op==3) printf("%d\n",has.query(nr));
	}
	return 0;
}