Pagini recente » Cod sursa (job #1602466) | Cod sursa (job #937425)
Cod sursa(job #937425)
#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cstring>
#define prim 1000000009
using namespace std;
class iHash
{
protected:
virtual int hash(int val) = 0;
virtual int hashFunction1(const int &val) = 0;
virtual int hashFunction2(const int &val) = 0;
public:
virtual int add(const int &val) = 0;
virtual int find(const int &val) = 0;
virtual int remove(const int &val) = 0;
};
class ChainingHash : public iHash
{
int size;
vector<int> *H;
int hash(int val) {return 1;}
int hashFunction1(const int &val)
{
return val%size;
}
int hashFunction2(const int &val) {return 1;}
public:
ChainingHash(int SIZE)
{
size = SIZE;
H = new vector<int>[size];
}
~ChainingHash()
{
delete[] H;
}
int add(const int &val)
{
const int m = hashFunction1(val);
int i, table_size = H[m].size();
for (i=0; i<table_size; ++i)
if (H[m][i] == val)
return -1; //se afla deja in hash
H[m].push_back(val);
return 1; //adaugat
}
int find(const int &val)
{
const int m = hashFunction1(val);
int i, table_size = H[m].size();
for (i=0; i<table_size; ++i)
if (H[m][i] == val)
{
//cout<<1<<endl;
return 1; //gasit
}
//cout<<0<<endl;
return 0; //nu exista in hash
}
int remove(const int &val)
{
const int m = hashFunction1(val);
int i, table_size = H[m].size();
for (i=0; i<table_size; ++i)
if (H[m][i] == val)
{
H[m][i] = H[m][table_size-1];
H[m].pop_back();
return 1; //sters
}
return 0; //nu exista in hash
}
};
class CuckooHash : public iHash
{
int a1, a2, b1, b2;
int size, *H1, *H2;
int hashFunction1(const int &val)
{
return ((1LL*a1*val + b1+1)%prim)%size;
}
int hashFunction2(const int &val)
{
return ((1LL*a2*val + b2+1)%prim)%size;
}
int hash(int val)
{
if (H1[hashFunction1(val)]==val || H2[hashFunction2(val)]==val)
return -1; //se afla deja in hash
int aux, val1, val2, i, old=val;
int inPlace = 0;
for (i=0; inPlace==0; ++i)
{
if (i>0 && val==old)
return 0; //ciclu
val1=hashFunction1(val); val2=hashFunction2(val);
if (H1[val1] == 0)
{
H1[val1] = val;
inPlace = 1;
}
else if (H2[val2] == 0)
{
H2[val2] = val;
inPlace = 1;
}
else
{
aux = H1[val1];
H1[val1]=val; val=aux;
val2 = hashFunction2(val);
if (H2[val2] == 0)
{
H2[val2] = val;
inPlace = 1;
}
else
{
aux = H2[val2];
H2[val2]=val; val=aux;
}
}
}
return 1; //adaugat cu succes;
}
public:
CuckooHash(int SIZE)
{
srand(time(NULL));
size = SIZE;
H1 = new int[size];
memset(H1, 0, sizeof(H1));
H2 = new int[size];
memset(H2, 0, sizeof(H2));
a1=rand()%size; a2=rand()%size;
b1=rand()%size; b2=rand()%size;
}
~CuckooHash()
{
delete[] H1;
delete[] H2;
}
int add(const int &val)
{
int canInsert = hash(val);
if (canInsert != 0)
return canInsert; //returneaza -1 pt element aflat deja in hash
//sau 1 pt element nou adaugat fara rehash
//Ciclu => rehash:
int *H1_temp = new int[size];
memcpy(H1_temp, H1, sizeof(H1));
int *H2_temp = new int[size];
memcpy(H2_temp, H2, sizeof(H2));
while (canInsert == 0)
{
a1=rand()%size; a2=rand()%size;
b1=rand()%size; b2=rand()%size;
delete[] H1; delete[] H2;
H1=new int[size]; memset(H1, 0, sizeof(H1));
H2=new int[size]; memset(H2, 0, sizeof(H2));
canInsert = 1;
for (int i=0; i<size &&canInsert==1; ++i)
{
if (H1_temp[i] > 0)
canInsert = hash(H1_temp[i]);
if (canInsert==1 && H2_temp[i]>0)
canInsert = hash(H2_temp[i]);
}
}
delete[] H1_temp;
delete[] H2_temp;
return 0; //inserat cu succes, dupa rehash
}
int find(const int &val)
{
int searchResult = (H1[hashFunction1(val)]==val || H2[hashFunction2(val)]==val);
//cout<<searchResult<<endl;
return searchResult;
}
int remove(const int &val))
{
int deleted = 0;
if (H1[hashFunction1(val)] == val)
{
deleted = 1;
H1[hashFunction1(val)] = 0;
}
else if (H2[hashFunction2(val)] == val)
{
deleted = 1;
H2[hashFunction2(val)] = 0;
}
return deleted;
}
};
int main()
{
/*int choice, value;
iHash *hash;
cout<<"ce metoda de hashing?\n\n1. chaining\n2. cuckoo\n\n";
cout<<"raspuns: "; cin>>choice;
switch (choice)
{
case 1: hash = new ChainingHash(1000000); break;
case 2: hash = new CuckooHash(1000000); break;
default: return -1;
}
cout<<"\nactiuni: (1 pt inserare, 2 pt cautare, 3 pt stergere, 0 pt oprire program)\n";
cout<<"-- DOAR INTREGI > 0 --\n>> "; cin>>choice;
while (choice)
{
cin>>value;
switch (choice)
{
case 1: hash->add(value); break;
case 2: hash->find(value); break;
case 3: hash->remove(value); break;
default: return -2;
}
cout<<">> "; cin>>choice;
}
return 0;*/
freopen("hashuri.in", "r", stdin);
freopen("hashuri.out", "w", stdout);
iHash *hash = new ChainingHash(666013);
int n, i, c, x;
scanf("%d", &n);
for (i=0; i<n; ++i)
{
scanf("%d%d", &c, &x);
switch (c)
{
case 1: hash->add(x); break;
case 2: hash->remove(x); break;
case 3: printf("%d\n", hash->find(x)); break;
}
}
return 0;
}