Cod sursa(job #719543)

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

#include <stdio.h>
#include <iostream>
#define MOD 199997
#define MOD2 199999

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];

	unsigned int h(MyType,int); // functia h este private, deoarece va fi apelata doar de metodele
	                            // insert, query si remove
	public:
		
	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){
		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){
		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 ((( int(x)+int(1000*(x-int(x)))%MOD)+i*(1+int(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<char *> has;
	unsigned short op,nr;
	float x;
	char c[30];
	scanf("%d",&n);
	for (register int i=1;i<=n;i++){
		cin>>op;
		cin.getline(c,300);
		if (op==1){ has.insert(c); continue;}
		if (op==2){ has.remove(c); continue;}
		if (op==3) printf("%d\n",has.query(c));
	}
	return 0;
}