Pagini recente » Cod sursa (job #3183852) | Cod sursa (job #3163046) | Cod sursa (job #2220821) | Cod sursa (job #1340431) | Cod sursa (job #922192)
Cod sursa(job #922192)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <typeinfo>
#include <sstream>
#define prim 1000000009
using namespace std;
template<class type> class Cuckoo
{
private:
int a1, a2, b1, b2;
int size, *H1, *H2;
//Trateaza orice input ca string, pe care-l converteste polinomial in numar
//In felul asta, hashul poate primi orice tip de date (alta metoda mai eficienta???)
int parse(type val)
{
ostringstream convert; convert<<val;
string str = convert.str();
unsigned int result=1<<31, i, SIZE=str.size(), xorVal, primescu=31;
for (i=0; i<SIZE; ++i)
//result = (1LL*result*256 + str[i])%prim;
{
xorVal = str[i];
result ^= xorVal;
result *= primescu;
}
return result%(1<<31-1);
}
int hashFunction1(int x)
{
return (1LL*a1*x + b1)%size;
}
int hashFunction2(int x)
{
return (1LL*a2*x + b2)%size;
}
int hash(int x)
{
if (H1[hashFunction1(x)]==x || H2[hashFunction2(x)]==x)
return -1; //se afla deja in hash
int aux, val1, val2, i, old=x;
bool inPlace = 0;
for (i=0; !inPlace; ++i)
{
if (i && x==old)
return 0; //ciclu
val1=hashFunction1(x); val2=hashFunction2(x);
if (H1[val1] == 0)
{
H1[val1] = x;
inPlace = 1;
}
else if (H2[val2] == 0)
{
H2[val2] = x;
inPlace = 1;
}
else
{
aux = H1[val1];
H1[val1]=x; x=aux;
val2 = hashFunction2(x);
if (H2[val2] == 0)
{
H2[val2] = x;
inPlace = 1;
}
else
{
aux = H2[val2];
H2[val2]=x; x=aux;
}
}
}
return 1; //adaugat cu succes
}
public:
Cuckoo(int SIZE)
{
srand(time(NULL));
size = SIZE;
H1 = (int*)calloc(size, sizeof(int));
H2 = (int*)calloc(size, sizeof(int));
a1=rand()%size; a2=rand()%size;
b1=rand()%size; b2=rand()%size;
}
Cuckoo()
{
srand(time(NULL));
size = rand()%250000 + 750001;
H1 = (int*)calloc(size, sizeof(int));
H2 = (int*)calloc(size, sizeof(int));
a1=rand()%size; a2=rand()%size;
b1=rand()%size; b2=rand()%size;
}
//Adaugare:
Cuckoo &operator <(type x)
{
int val = parse(x);
int canInsert = hash(val);
//Ciclu => rehash:
if (!canInsert)
{
int *H1_temp = (int*)malloc(size*sizeof(int));
memcpy(H1_temp, H1, size*sizeof(int));
int *H2_temp = (int*)malloc(size*sizeof(int));
memcpy(H2_temp, H2, size*sizeof(int));
while (!canInsert)
{
a1=rand()%size; a2=rand()%size;
b1=rand()%size; b2=rand()%size;
free(H1); free(H2);
H1 = (int*)calloc(size, sizeof(int));
H2 = (int*)calloc(size, sizeof(int));
canInsert = 1;
for (int i=0; i<size && canInsert==1; ++i)
{
if (H1_temp[i])
canInsert = hash(H1_temp[i]);
if (canInsert==1 && H2_temp[i])
canInsert = hash(H2_temp[i]);
}
}
free(H1_temp);
free(H2_temp);
}
return *this;
}
//interogare:
Cuckoo &operator <=(type x)
{
int val = parse(x);
printf("%d\n", H1[hashFunction1(val)]==val || H2[hashFunction2(val)]==val);
return *this;
}
//Stergere:
Cuckoo &operator >(type x)
{
int val = parse(x);
if (H1[hashFunction1(val)] == val)
H1[hashFunction1(val)] = 0;
else if (H2[hashFunction2(val)] == 0)
H2[hashFunction2(val)] = 0;
return *this;
}
//Inutil momentan:
bool find(type x)
{
int val = parse(x);
return (H1[hashFunction1(val)]==val || H2[hashFunction2(val)]==val);
}
};
int main()
{
freopen("hashuri.in", "r", stdin);
freopen("hashuri.out", "w", stdout);
int n, c, x, i;
Cuckoo<int> H;
scanf("%d", &n);
for (i=0; i<n; ++i)
{
scanf("%d%d", &c, &x);
switch (c)
{
case 1: H <x; break;
case 2: H >x; break;
case 3: H <=x; break;
}
}
return 0;
}