Pagini recente » Cod sursa (job #2816950) | Cod sursa (job #2973749) | Statistici Pacurari Sofia (Pacurari_Sofia) | Cod sursa (job #1882208) | Cod sursa (job #708705)
Cod sursa(job #708705)
// Ion Vlad-Doru, Grupa 135, Facultatea de Matematica si Informatica
// Cuckoo Hashing
#include <fstream>
#include <cmath>
#include <cstdlib>
#define NA -1
#define FREE 0
using namespace std;
ifstream in("hashuri.in");
ofstream out("hashuri.out");
int prime[]={7, 23, 79, 1087, 66047, 263167, 1000003, 2097593, 16785407, 1073807359};
int prime_size=9;
/*lista de numere prime pentru a alege numarul prim potrivit pentru functii de hash in functie de dimensiunea hashului*/
//Lista de numere prime poate fi citita si dintr-un fisier text pregenerat;
int find_prim(int x); // cauta binar numarul prim din lista mai mare decat x;
class hash_function{ // h(x)=((a*x+b)%p)%m unde a si b sunt random si a!=0
int a,b,p,m;
public:
void generate(int prim,int h_size);
int evaluate(int x);
};
void hash_function::generate(int prim,int h_size){
this->p=prim;
this->m=h_size;
this->a=(rand())%(this->m);
while(this->a==0) // ne asiguram ca a e diferit de 0
this->a=(rand())%(this->m);
this->b=(rand())%(this->m);
return;
}
int hash_function::evaluate(int x){
long long value;
value=(long long)((long long)a*(long long)x+(long long)b);
value%=p;
value%=m;
return (int)value;
}
class hash{
int size; // dimensiunea hashului
int *h; // vom aloca dinamic un vector h de dimensiune size
int p; // p numar random folosit pentru functiile de hash
hash_function h1,h2;
public:
hash(int hash_size);
~hash();
int find(int value);
void erase(int value);
bool insert(int value); // returneaza 1 daca insereaza cu succes si 0 fara succes ceea ce implica refacerea hashului
};
hash::hash(int hash_size){
this->size=hash_size;
this->h=new int[this->size +1 ];
for(int i=0;i<=size;++i)
h[i]=0;
this->p=find_prim(hash_size);
this->h1.generate(this->p,this->size - 1);
this->h2.generate(this->p,this->size - 1);
}
hash::~hash(){
delete[] this->h;
}
int hash::find(int value){
int locate1=this->h1.evaluate(value),locate2=this->h2.evaluate(value);
if(h[locate1]==value)
return locate1;
if(h[locate2]==value)
return locate2;
return NA;
}
void hash::erase(int value){
int location=find(value);
if(location!=NA)
h[location]=FREE;
}
bool hash::insert(int value){
int aux,ant=value,location1,location2,explorated=0,upper_bound=(int)log((double)size);
location1=h1.evaluate(value);
if(h[location1]==FREE){
h[location1]=value;
return true;
}
else{
aux=h[location1];
h[location1]=value;
explorated++;
}
while(explorated<upper_bound){
location1=h1.evaluate(aux);
location2=h2.evaluate(aux);
if(h[location2]==ant){
if(h[location1]==FREE){
h[location1]=aux;
return true;
}
else{
ant=aux;
aux=h[location1];
h[location1]=ant;
}
}
else{
if(h[location2]==FREE){
h[location2]=aux;
return true;
}
else{
ant=aux;
aux=h[location2];
h[location2]=ant;
}
}
explorated++;
}
return false;
}
int main(){
hash H(1200000);
int operations,value,opcode;
in>>operations;
for(int i=1;i<=operations;++i){
in>>opcode>>value;
if(opcode==1)
H.insert(value);
if(opcode==2)
H.erase(value);
if(opcode==3){
if(H.find(value)==NA)
out<<"0\n";
else
out<<"1\n";
}
}
return 0;
}
int find_prim(int x){
int i,pas;
for(pas=1;pas<=prime_size;pas<<=1);
for(i=0;pas;pas>>=1){
if(i+pas<prime_size && prime[i+pas]<=x)
i+=pas;
}
return prime[i+1]; // returnam cel mai mic numar prim mai mare decat x din lista de prime
}