Pagini recente » Cod sursa (job #459475) | Cod sursa (job #2545812) | Cod sursa (job #1267570) | Cod sursa (job #2202406) | Cod sursa (job #719643)
Cod sursa(job #719643)
//Laceanu Ionut-Adrian
//Double Hashing cu Template
//F.M.I., gr.135
#include <stdio.h>
#include <fstream>
#define MOD 1000003
#define MOD2 1000001
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; // sa suporte testul de egalitate (==)
char *sters;
char *ocupat;
unsigned int h(MyType,int); // functia h este private, deoarece va fi apelata doar de metodele
// insert, query si remove
public:
hash(){
T=new MyType[MOD];
sters=new char[MOD];
ocupat=new char[MOD];
for (int i=0;i<MOD;i++){
T[i]=0;
sters[i]=0;
ocupat[i]=0;
}
}
~hash(){
delete[] T;
delete[] sters;
delete[] ocupat;
}
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
int intreaga=(int)x;
int fract=int(1000*(x-intreaga));
return ((((intreaga+fract)%MOD)+i*(1+(intreaga+fract)%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;
}