Pagini recente » Cod sursa (job #2077278) | Cod sursa (job #2495659) | Cod sursa (job #2452147) | Cod sursa (job #493708) | Cod sursa (job #719554)
Cod sursa(job #719554)
//Laceanu Ionut-Adrian
//Double Hashing cu Template
//F.M.I., gr.135
#include <stdio.h>
#include <fstream>
#define MOD 1000001
#define MOD2 1000003
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;
ifstream fin("hashuri.in");
freopen("hashuri.out","w",stdout);
unsigned short op,nr;
float x;
char c[30];
fin>>n;
for (register int i=1;i<=n;i++){
fin>>op;
fin.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;
}