Cod sursa(job #922259)

Utilizator UnforgivenMihai Catalin Botezatu Unforgiven Data 22 martie 2013 00:10:08
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 6.65 kb
#include <fstream>
#include <cstdlib>
#include <time.h>
#include <string.h>
#include <string>
#include <vector>
#include <iostream>

using namespace std;

class Hash_Function
{
private:
    int a , b;
    int prim;
    int size;

public:
    Hash_Function(int &);
    void generate();
    int hash_function(int&);
    int hash_function(float&);
    int hash_function(double&);
    int hash_function(char&);
    int hash_function(string&);
};

Hash_Function::Hash_Function(int &max)
{
    prim = 1000000009;
    size = max;
    generate();
}

void Hash_Function::generate()
{
    a = rand() % size;
    b = rand() % size;
}

int Hash_Function::hash_function(char &value)
{
    return (((long long)a + (long long)value * (long long)b ) % (long long)prim) % (long long)size;
}

int Hash_Function::hash_function(int &value)
{
    return (((long long)a + (long long)value * (long long)b ) % (long long)prim) % (long long)size;
}

int Hash_Function::hash_function(float &value)
{
    while ((value - (int)value) != 0)
    {
        value *= 10;
        if (value > size)
        {
            value -= size;
        }
    }
    return (((long long)a + (long long)value * (long long)b ) % (long long)prim) % (long long)size;
}

int Hash_Function::hash_function(double &value)
{
    while ((value - (int)value) != 0)
    {
        value *= 10;
        if (value > size)
        {
            value -= size;
        }
    }
    return (((long long)a + (long long)value * (long long)b ) % (long long)prim) % (long long)size;
}

int Hash_Function::hash_function(string &value)
{
    int key = 0;
    for (int i =0;i<value.size();i++)
    {
        key += (a + (int)(value[i]) * b);
        key %= size;
    }
    return key;
}

template <class Data>
class Hash_Set
{
    int modulo;
    Data *hash1;
    Data *hash2;
    bool *viz1;
    bool *viz2;
    int hash_size;
    Hash_Function *func1;
    Hash_Function *func2;
    //ofstream out("hashuri.out");

    vector < pair<char,Data> > temp;

    public:
    Hash_Set<Data>(int);
    ~Hash_Set<Data>();

    bool add(Data &);
    void erase(Data &);
    bool find(Data &);

    void erase_all();
    void operator *= (Data&);
    void operator /= (Data&);
    bool operator %= (Data&);

    Hash_Set& operator * (Data&);
    Hash_Set& operator / (Data&);
    Hash_Set& operator % (Data&);

    void read_file (char *);
};

template <class Data>
bool Hash_Set<Data>::add(Data & value)
{
    if (find(value)) return true;
    char which = 1;
    for (int i =0;i<30;i++)
    {
        int h1 = func1->hash_function(value);
        int h2 = func2->hash_function(value);
        if (viz1[h1] == false)
        {
            hash1[h1] = value;
            viz1[h1] = true;
            return true;
        }
        else if(viz2[h2] == false)
        {
            hash2[h2] = value;
            viz2[h2] = true;
            return true;
        }
        else
        {
            if (which == 1)
            {
                Data aux = value;
                value = hash1[h1];
                hash1[h1] = aux;
                viz1[h1] = true;
            }
            else
            {
                Data aux = value;
                value = hash2[h2];
                hash2[h2] = aux;
                viz2[h2] = true;
            }
            which = - which;
        }
    }

    return false;
}

template <class Data>
void Hash_Set<Data>::erase(Data & value)
{
     int h1 = func1->hash_function(value);
     int h2 = func2->hash_function(value);
     if (hash1[h1] == value && viz1[h1] == true)
     {
        viz1[h1] = false;
     }
     else if (hash2[h2] == value && viz2[h2] == true)
     {
        viz2[h2] = false;
     }
}

template <class Data>
bool Hash_Set<Data>::find(Data & value)
{
     int h1 = func1->hash_function(value);
     int h2 = func2->hash_function(value);
     if (hash1[h1] == value && viz1[h1] == true)
     {
        return true;
     }
     else if (hash2[h2] == value && viz2[h2] == true)
     {
        return true;
     }
     else
     {
         return false;
     }
}


template <class Data>
void Hash_Set<Data>::read_file (char * file_input)
{
    ifstream input(file_input);
    ofstream output("hashuri.out");
    int n;
    func1->generate();
    func2->generate();
    input >> n;
    for (int i =0;i<n;i++)
    {
        int op;
        Data x;
        input >> op >> x;
        if (op == 1)
        {
            *this *= x;
        }
        if (op == 2)
        {
            *this /= x;
        }
        if (op == 3)
        {
            output << (*this %= x) << "\n";
        }
    }
    int h = 3;
    //*this % h / h % h * h % h;

}


int main()
{
    Hash_Set<int> t(1000000);
    t.read_file("hashuri.in");
    int h = 3;
    return 0;
}


template <class Data>
Hash_Set<Data>::Hash_Set(int size)
{
    hash1 = new Data[size];
    hash2 = new Data[size];
    viz1 = new bool[size];
    viz2 = new bool[size];
    hash_size = size;

    func1 = new Hash_Function(size);
    func2 = new Hash_Function(size);

    fill(viz1,viz1+size,false);
    fill(viz2,viz2+size,false);

    func1->generate();
    func2->generate();
}

template <class Data>
Hash_Set<Data>::~Hash_Set()
{
    delete[] hash1;
    delete[] hash2;
    delete[] viz1;
    delete[] viz2;
}

template <class Data>
void Hash_Set<Data>::erase_all()
{
    fill(viz1,viz1+hash_size,false);
    fill(viz2,viz2+hash_size,false);
}

template <class Data>
void Hash_Set<Data>::operator /= (Data &value)
{
     temp.push_back(make_pair(2,value));
     erase(value);
}

template <class Data>
bool Hash_Set<Data>::operator %= (Data &value)
{
    return find(value);
}

template <class Data>
void Hash_Set<Data>::operator *= (Data &value)
{
    temp.push_back(make_pair(1,value));
    if (add(value) == false)
    {
        bool ok = false;
        while (ok == false)
        {
            func1->generate();
            func2->generate();
            erase_all();
            for (int i =0;i<(int)temp.size();i++)
            {
                int op = temp[i].first;
                Data val = temp[i].second;
                if (op == 1)
                {
                    if (add(val))
                    {
                        ok = false;
                        break;
                    }
                }
                if (op == 2)
                {
                    erase(val);
                }
            }
        }

    }
}

template <class Data>
Hash_Set<Data>& Hash_Set<Data>::operator *(Data & value)
{
    *this *= value;
    return *this;
}


template <class Data>
Hash_Set<Data>& Hash_Set<Data>::operator /(Data & value)
{
    *this /= value;
    return *this;
}

template <class Data>
Hash_Set<Data>& Hash_Set<Data>::operator %(Data & value)
{
    bool ok = (*this %= value);
    cout << ok << " ";
    return *this;
}