Cod sursa(job #937731)

Utilizator blechereyalBlecher Eyal blechereyal Data 10 aprilie 2013 22:40:33
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 7.49 kb
#include <math.h>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <math.h>
#include <vector>

using namespace std;
template <class type>
class base_hash
{
    public:
    base_hash <type> (){;}
    virtual bool operator +=(type)=0;
    virtual bool operator -=(type)=0;
    virtual bool operator ==(type)=0;
    virtual int function (type,int,int)=0;
    virtual int hash_from_data(string,string)=0;
};

template <class type>
class cuckoo_hash:public base_hash <type> {
    private:
    type *h1,*h2;
    int hash_size;
    int a,b;
    long long prim;

    public:
    cuckoo_hash<type>(int size,int p=1000000009)
    {
        h1 = new type[size];
        h2 = new type[size];
        hash_size = size;
        fill(h1,h1+size,0);
        fill(h2,h2+size,0);
        prim=p;
    }

    ~cuckoo_hash()
    {
       delete [] h1;
       delete [] h2;
       a=b=hash_size=0;
       prim=0;
    }
    bool operator +=(type value)
    {
    int cycles=0,sw=1;
    type aux=value;
    bool found=false;

    if (*(this) == value) return true;

    while (!found)
    {
                int poz1 = function(value,a,b);
                int poz2 = function(value,b,a);
                cycles++;
                if (h1[poz1] == 0)
                    {
                    h1[poz1] = value;
                    found = true;
                    }
                else if(h2[poz2] == 0)
                    {
                    h2[poz2] = value;
                    found = true;
                    }
                    else
                        {
                        if (sw==1)
                            {
                            aux = value;
                            value = h1[poz1];
                            h1[poz1] = aux;
                            }
                        else
                            {
                            aux = value;
                            value = h2[poz2];
                            h2[poz2] = aux;
                            }
                        sw*=-1;
                        }
            if ((cycles > log2(this->hash_size))&&(!found)){return false;} //numarul de incercari nu depaseste log size
    }
    return true;
    }

    bool operator -=(type value)
    {

        int poz1 = function(value,a,b);
        int poz2 = function(value,b,a);
        if (h1[poz1] == value)
            {
            h1[poz1] = 0;
            return true;
            }
        else if (h2[poz2] == value)
            {
            h2[poz2] = 0;
            return true;
            }
        return false;
    }

    bool operator ==(type value)
    {
    int poz1 = function(value,a,b);
    int poz2 = function(value,b,a);
    if (h1[poz1] == value || h2[poz2] == value)
    {
        return true;
    }
    else
    {
        return false;
    }
    }

    //define function for each type
    int function(int value,int a,int b)
    {

        return (((long long)a+(long long)value * (long long)b ) % (long long)prim )% (long long)hash_size;
    }
    int function(float value,int a,int b)
    {
        value=value*(0.61);
        double integral,fractionary;
        fractionary=modf(value,&integral);
        return (((long long)fractionary+(long long)integral * (long long)b ) % (long long)prim )% (long long)hash_size;
    }
    int function(double value,int a,int b)
    {
        value=value*(0.61);
        double integral,fractionary;
        fractionary=modf(value,&integral);
        return (((long long)fractionary+(long long)integral * (long long)b ) % (long long)prim )% (long long)hash_size;
    }
    int function(char value,int a,int b)
    {

        return (((long long)a+(long long)(int(value)) * (long long)b ) % (long long)prim )% (long long)hash_size;
    }
    void make_hash_function()
    {
         a = rand() % hash_size;
         b = rand() % hash_size;
    }
    int hash_from_data (string a, string b)
    {
    bool ok = false;
    ifstream in(a.c_str());
    ofstream out(b.c_str());

    while (ok == false)
    {

        in.clear();

        int N;

        make_hash_function();
        in >> N;
        for (int i =0;i<N;i++)
        {

            type x ;int op;
            in >> op >> x;
            if (op==1)
                if ( (*(this)+=x) == false )
                {
                    ok = false;
                    break;
                }
            if (op==2)
                *(this)-=x;
            if (op==3)
                out << (*(this) == x) << "\n";
        }
        ok = true;
    }
    return 0;
    }
};

template <class type>
class simple_hash:public base_hash <type> {
    private:
    vector <type> *H;
    //typename vector <type>::iterator it;
    int hash_size,a,b;
    long long prim;

    public:
    simple_hash <type>(int size,int p=666013)
    {
        H = new vector<type> [size];
        hash_size=size;
        a=b=0;
        prim=p;
    }

    ~simple_hash()
    {
       delete [] H;
       hash_size=0;
       prim=0;
    }
    bool operator +=(type value)
    {int poz;
    poz=function(value,a,b);
    H[poz].push_back(value);
    return true;
    }

    bool operator -=(type value)
    {
        typename vector<type>::iterator it;
        int poz = function(value,a,b);
        for (it=H[poz].begin();it!=H[poz].end();it++)
            if ((*it)==value)
                {
                    H[poz].erase(it);
                    return true;
                }
        return false;
    }

    bool operator ==(type value)
    {
        typename vector<type>::iterator it;
        int poz = function(value,a,b);
        for (it=H[poz].begin();it!=H[poz].end();it++)
            if (*it==value) return 1;

        return 0;
    }

    //define function for each type
    int function(int value,int a,int b)
    {

        return (((long long)a+(long long)(int(value)) * (long long)b ) % (long long)prim )% (long long)hash_size;
    }
    int function(float value,int a,int b)
    {
        value=value*(0.61);
        double integral,fractionary;
        fractionary=modf(value,&integral);
        return (((long long)fractionary+(long long)integral * (long long)b ) % (long long)prim )% (long long)hash_size;
    }
    int function(double value,int a,int b)
    {
        value=value*(0.61);
        double integral,fractionary;
        fractionary=modf(value,&integral);
        return (((long long)fractionary+(long long)integral * (long long)b ) % (long long)prim )% (long long)hash_size;
    }
    int function(char value,int a,int b)
    {

        return (((long long)a+(long long)(int(value)) * (long long)b ) % (long long)prim )% (long long)hash_size;
    }
    void make_hash_function()
    {
         a = rand() % hash_size;
         b = rand() % hash_size;
    }
    int hash_from_data (string a, string b)
    {
    ifstream in(a.c_str());
    ofstream out(b.c_str());
    int N;
    make_hash_function();
    in >> N;
        for (int i =0;i<N;i++)
        {

            type x ;int op;
            in >> op >> x;
            if (op==1)
                *this+=x;
            if (op==2)
                *(this)-=x;
            if (op==3)
                out << (*(this) == x) << "\n";
        }

    return 0;
    }
};


int main()
{   base_hash <int> *t;
    t=new simple_hash<int>(1000005);
    t->hash_from_data("hashuri.in","hashuri.out");
   return 0;
}