Cod sursa(job #921426)

Utilizator Aida_SilviaStrimbeanu Aida Silvia Aida_Silvia Data 20 martie 2013 23:18:55
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.65 kb
#include<fstream>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<string>

using namespace std;

#define ll long long

class Functii
{
    int a , b;
    int mod;
    const static int prime_nr = 1000000009;
    public:
    Functii(int size)
    {
        this->mod = size;
    }

    void generate()
    {
        a = rand() % this->mod;
        b = rand() % this->mod;
    }

    int hash(int val)
    {
        return ( ( ( (ll)this->a * (ll)val + (ll)this->b) % (ll)this->prime_nr ) % (ll)this->mod );
    }

    int hash(char val)
    {
        return ( ( ( this->a * val + this->b) % this->prime_nr ) % this->mod );
    }

    int hash(float val)
    {

    }
    int hash(double val)
    {

    }

    int hash(string val)
    {

    }

};

template <class Tip>
class cockooHash
{
    int table_size, max_steps;
    Tip *h1 , *h2;
    bool *viz1, *viz2;

    Functii *f1 , *f2;


    public:

    cockooHash(int dim)
    {
        this->table_size = dim;
        this->max_steps = (int)log2(this->table_size);

        this->h1 = new Tip[this->table_size];
        this->h2 = new Tip[this->table_size];

        this->viz1 = new bool[this->table_size];
        this->viz2 = new bool[this->table_size];
        fill(this->viz1, this->viz1+this->table_size, false);
        fill(this->viz2, this->viz2+this->table_size, false);

        f1 = new Functii(dim);
        f1->generate();
        f2 = new Functii(dim);
        f2->generate();


    }

    ~cockooHash()
    {
        delete[] h1;
        delete[] h2;
        delete[] viz1;
        delete[] viz2;
        delete f1;
        delete f2;
    }

    bool find(Tip val)
    {
        int k1, k2;

        k1 = f1->hash(val);
        k2 = f2->hash(val);

        if(this->h1[k1] == val && this->viz1[k1] == true)
            return true;
        if(this->h2[k2] == val && this->viz2[k2] == true)
            return true;

        return false;
    }

    bool erase(Tip val)
    {
        int k1 = f1->hash(val);
        int k2 = f2->hash(val);

        if(this->h1[k1] == val && this->viz1[k1] == true)
        {
            this->viz1[k1] = false;
            return true;
        }
        if(this->h2[k2] == val && this->viz2[k2] == true)
        {
            this->h2[k2] = 0;
            this->viz2[k2] = false;
            return true;
        }

        return false;
    }

    bool insert(Tip val)
    {
        Tip x = val;
        int k1 = f1->hash(x);
        int k2 = f2->hash(x);

        if(this->viz1[k1] == false)
        {
            this->h1[k1] = x;
            this->viz1[k1] = true;
            return true;
        }

        for(int i = 0; i<this->max_steps; i+=2)
        {
            if(this->viz2[k2] == false)
            {
                this->h2[k2] = x;
                this->viz2[k2] = true;
                return true;
            }

            swap(x, this->h2[k2]);
            k1 = f1->hash(x);
            k2 = f2->hash(x);

            if(this->viz1[k1] == false)
            {
                this->h1[k1] = x;
                this->viz1[k1] = true;
                return true;
            }

            swap(x, this->h1[k1]);
            k1 = f1->hash(x);
            k2 = f2->hash(x);
        }

        return false;
    }

    void do_hash()
    {
        bool ok = false;
        while (ok == false)
        {
            ok = true;
            ifstream f("hashuri.in");
            ofstream g("hashuri.out");
            f1->generate();
            f2->generate();
            int n,op,x;
            f>>n;
            for (int i=1;i<=n && ok;i++)
            {
                f>>op>>x;
                if (op == 1)
                {
                    if(this->find(x) == false) {
                                     bool ok2 = this->insert(x);
                                     if(ok2 == false) {
                                            ok = false;
                                             break;
                                     }
                    }
                    continue;
                }
                if(op == 2) {
                      if(this->find(x) == true)
                                       this->erase(x);
                      continue;
                }
                else
                     g<<this->find(x)<<"\n";

            }

            f.close();
            g.close();
        }
    }

};

int main()
{
    cockooHash <int> *hash;
    hash=new cockooHash<int>(1000000);
    hash->do_hash();
    delete hash;
    hash = 0;

    return 0;

}