Cod sursa(job #907799)

Utilizator UnforgivenMihai Catalin Botezatu Unforgiven Data 8 martie 2013 12:42:35
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.87 kb
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <string.h>

using namespace std;

class Hash_Set
{
    int modulo;
    int *hash1;
    int *hash2;
    int hash_size;
    int va1;
    int vb1;
    int va2;
    int vb2;
    int prim;
    char * file_input;
    char * file_output;


    public:
    Hash_Set(int , char * , char *);
    ~Hash_Set();

    void erase_all();
    bool insert(int&);
    void erase(int&);
    bool find(int&);
    int hash_function1(int&);
    int hash_function2(int&);
    void make_hash_function();
    void Build_Hash_From_File();
};

void Hash_Set::Build_Hash_From_File()
{
    bool ok = false;
    srand(time(0));

    int mod;
    while (ok == false)
    {

        ifstream input(file_input);
        ofstream output(file_output);
        int n;
        make_hash_function();
        input >> n;
        for (int i =0;i<n;i++)
        {
            int x , op;
            input >> op >> x;
            if (op == 1)
            {
                if ( !insert(x) )
                {
                    ok = false;
                    break;
                }
            }
            if (op == 2)
            {
                erase(x);
            }
            if (op == 3)
            {
                output << find(x) << "\n";
            }
        }
        ok = true;
    }
}


int main()
{
    Hash_Set t(1000000,"hashuri.in","hashuri.out");
    t.Build_Hash_From_File();
    return 0;
}



Hash_Set::Hash_Set(int size , char* in , char* out )
{
    hash1 = new int[size];
    hash2 = new int[size];
    hash_size = size;
    prim = 1000000009;
    fill(hash1,hash1+size,0);
    fill(hash2,hash2+size,0);
    file_input = new char[strlen(in)];
    file_output = new char[strlen(out)];
    strcpy(file_input,in);
    strcpy(file_output,out);
}

Hash_Set::~Hash_Set()
{
    delete[] hash1;
    delete[] hash2;
    delete[] file_input;
    delete[] file_output;
}

void Hash_Set::erase_all()
{
    fill(hash1,hash1+hash_size,0);
    fill(hash2,hash2+hash_size,0);
}

void Hash_Set::make_hash_function()
{
    va1 = rand() % hash_size;
    vb1 = rand() % hash_size;
    va2 = rand() % hash_size;
    vb2 = rand() % hash_size;
}

int Hash_Set::hash_function1(int &value)
{
    return (((long long)va1 + (long long)value * (long long)vb1 ) % (long long)prim) % (long long)hash_size;
}

int Hash_Set::hash_function2(int &value)
{
    return (((long long)va2 + (long long)value * (long long)vb2) % (long long)prim) % (long long)hash_size;
}

void Hash_Set::erase(int &value)
{
     int h1 = hash_function1(value);
     int h2 = hash_function2(value);
     if (hash1[h1] == value)
     {
        hash1[h1] = 0;
     }
     else if (hash2[h2] == value)
     {
        hash2[h2] = 0;
     }
}

bool Hash_Set::find(int &value)
{
    int h1 = hash_function1(value);
    int h2 = hash_function2(value);
    if (hash1[h1] == value || hash2[h2] == value)
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool Hash_Set::insert(int &value)
{
    if (find(value)) return true;
    int init = value;
    char which = 1;
    int iteratii = 0;
    while (value != 0)
    {
        iteratii++;
        int h1 = hash_function1(value);
        int h2 = hash_function2(value);
        if (hash1[h1] == 0)
        {
            hash1[h1] = value;
            value = 0;
        }
        else if(hash2[h2] == 0)
        {
            hash2[h2] = value;
            value = 0;
        }
        else
        {
            if (which == 1)
            {
                int aux = value;
                value = hash1[h1];
                hash1[h1] = aux;
            }
            else
            {
                int aux = value;
                value = hash2[h2];
                hash2[h2] = aux;
            }
            which = - which;
        }
        if (iteratii > 30)
        {
            return false;
        }
    }

    return true;
}