Cod sursa(job #937413)

Utilizator razvan9310FMI - Razvan Damachi razvan9310 Data 10 aprilie 2013 11:45:57
Problema Hashuri Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 7.1 kb
#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(int val) = 0;
        virtual bool find(int val) = 0;
        virtual bool remove(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(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
        }

        bool find(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
        }

        bool remove(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;
        bool 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(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
        }

        bool find(int val)
        {
            int searchResult = (H1[hashFunction1(val)]==val || H2[hashFunction2(val)]==val);
            cout<<searchResult<<endl;
            return searchResult;
        }

        bool remove(int val)
        {
            bool 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;*/
    ifstream in("hashuri.in"); ofstream out("hashuri.out");
    int n, i, choice, value;
    iHash *hash = new ChainingHash(666013);

    in>>n;
    for (i=0; i<n; ++i)
    {
        in>>choice>>value;
        switch (choice)
        {
            case 1: hash->add(value); break;
            case 2: hash->remove(value); break;
            case 3: out<<hash->find(value)<<endl; break;
        }
    }
    return 0;
}