Pagini recente » Cod sursa (job #55314) | Cod sursa (job #66616) | Cod sursa (job #725283) | Cod sursa (job #2462729) | Cod sursa (job #730093)
Cod sursa(job #730093)
//hashing with open adressing
//fara var globale & clasa cu template, specializari pt: int, double, char si string
//h(x) = (h'(x) + r1 * i + r2 * i^2) % M
//Florea Daniel-Ciprian, gr. 135.
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<cstring>
using namespace std;
template <class T> //pt int si double
class Hash
{
private:
int r1,r2;
static const int nmax=1000;
bool *sters; //vector in care marchez elementele sterse
T *v; //vectorul pt hashing
int n;
public:
Hash (int nr) //constructor
{
n=nr;
//vectorul
v = new T [nmax]; //nu pot declara static un vector mare
sters = new bool [nmax];
memset (v,0,sizeof(v)*nmax);
//initializam 2 valori random pt functia de hash
srand(time(NULL));
r1=rand()%nmax;
r2=rand()%nmax;
}
~Hash () //destructor
{
delete[] v;
}
int has (int x, int i)//pt <int>
{
int rez=abs((x%nmax+r1*i+r2*i*i))%nmax;
return rez;
}
int has (double x, int i)//pt <double>
{ //h(x)=[ {knuth*x} * nmax ] + r1*i + r2*i*i
double knuth=0.618033988749894L;
int rez=abs( (int((knuth*x - int(knuth*x))*nmax)) %nmax+r1*i+r2*i*i )%nmax;
return rez;
}
void inserare (T x)
{
int k=0;
while (v[has(x,k)]!=0 && k<=nmax)
k++;
if (k>=n+1)
{
cout<<"Vectorul este plin!";
return;
}
v[has(x,k)]=x;
sters[has(x,k)]=0;
//cout<<"ASD"<<x;
}
void stergere (T x)
{
int k=0;
while (v[has(x,k)]!=x && (v[has(x,k)]!=0 || sters[has(x,k)]==1) && k<=nmax)
k++;
if (v[has(x,k)]==0) return;
else if (k<=n)
{
v[has(x,k)]=0;
sters[has(x,k)]=1;
}
}
bool cautare (T x)
{
int k=0;
while (v[has(x,k)]!=x && (v[has(x,k)]!=0 || sters[has(x,k)]==1) && k<=nmax)
k++;
if (k<=n && v[has(x,k)]==x) return 1;
else return 0;
}
void afisare ()
{
cout<<"V= ";
for (int i=0;i<nmax;++i)
cout<<v[i]<<' ';
cout<<endl;
}
};
template <>
class Hash <string> //specializare pt string din cauza unor diferente la stergere si verificari
{
private:
int r1,r2;
static const int nmax=1000;
bool *sters; //vector in care marchez elementele sterse
string *v; //vectorul pt hashing
int n;
public:
Hash (int nr) //constructor
{
n=nr;
//vectorul
v = new string [nmax]; //nu pot declara static un vector mare
sters = new bool [nmax];
for (int i=0;i<nmax;++i)
{
v[i]=""; //memset-ul nu mi-a iesit pt stringuri, varianta asta este mai convenabila
sters[i]=0;
}
//initializam 2 valori random pt functia de hash
srand(time(NULL));
r1=rand()%nmax;
r2=rand()%nmax;
}
~Hash () //destructor
{
delete[] v;
}
int has (string x, int i)//pt <string>
{
unsigned int sum=0;
int j;
for (j=0;j+4<x.length();j+=4)
sum+=x[j] + 128*x[j+1] + 128*128*x[j+2] + 128*128*128*x[j+3];
while (j<=x.length())
{
sum+=x[j];
++j;
}
int rez=(sum%nmax+r1*i+r2*i*i)%nmax;
return rez;
}
void inserare (string x)
{
int k=0;
while (v[has(x,k)]!="" && k<=nmax)
k++;
if (k>=n+1)
{
cout<<"Vectorul este plin!";
return;
}
v[has(x,k)]=x;
sters[has(x,k)]=0;
}
void stergere (string x)
{
int k=0;
while (v[has(x,k)]!=x && (v[has(x,k)]!="" || sters[has(x,k)]==1) && k<=nmax)
k++;
if (v[has(x,k)]=="") return;
else if (k<=n)
{
v[has(x,k)]="";
sters[has(x,k)]=1;
}
}
bool cautare (string x)
{
int k=0;
while (v[has(x,k)]!=x && (v[has(x,k)]!="" || sters[has(x,k)]==1) && k<=nmax)
k++;
if (k<=n && v[has(x,k)]==x) return 1;
else return 0;
}
void afisare ()
{
cout<<"V= ";
for (int i=0;i<nmax;++i)
cout<<v[i]<<' ';
cout<<endl;
}
};
template <>
class Hash <char> //specializare separata pt char pt ca e foarte simplu
{
private:
bool v[127];
public:
Hash (int n) //ignoram n-ul
{
for (int i=0;i<127;i++)
v[i]=0;
}
void inserare (char x)
{
if (v[int(x)]==0)
v[int(x)]=1;
}
void stergere (char x)
{
if (v[int(x)]==1)
v[int(x)]=0;
}
bool cautare (char x)
{
if (v[int(x)]==1)
return 1;
else
return 0;
}
void afisare ()
{
cout<<"V= ";
for (int i=0;i<127;++i)
cout<<v[i]<<' ';
cout<<endl;
}
};
int main ()
{
ifstream fin ("hashuri.in");
ofstream fout ("hashuri.out");
int op,n;
fin>>n;
Hash <int> h(n);
int x;
for (int i=1;i<=n;i++)
{
fin>>op>>x;
/* PT STRING
//getline(fin,x);
//x=x.substr(1); //elimin spatiul
*/
if (op==1) { if (!h.cautare(x)) h.inserare(x); }
else if (op==2) h.stergere(x);
else if (op==3) fout<<h.cautare(x)<<'\n';
}
fin.close();
fout.close();
return 0;
}