Cod sursa(job #906935)

Utilizator cdascaluDascalu Cristian cdascalu Data 7 martie 2013 14:21:54
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 6.44 kb
//Pentru detalii:
//http://stackoverflow.com/a/98179
//http://www.isthe.com/chongo/tech/comp/fnv/
//(numerele sunt siruri de caractere)
#include <fstream>
#include <vector>
#define Nmax 699967
using namespace std;
class FNV_Hash
{
    public:
 
        FNV_Hash(unsigned int size);
        ~FNV_Hash();
 
        unsigned int       hash_function(int elem);
        void                insert_element(int elem);
        void                remove_element(int elem);
        bool                check_element(int elem);
    private:
 
        unsigned int             hash_size;
        unsigned int             FNV_prime;
        unsigned int             FNV_init;
 
        vector<int>               *hash_vector;
};
int main()
{
    FNV_Hash *my_hash;
    my_hash = new FNV_Hash(Nmax);
 
    ifstream f("hashuri.in");
    ofstream g("hashuri.out");
    int N,op,val;
    f>>N;
    while(N--)
    {
        f>>op>>val;
        if(op == 3)
        {
            if(my_hash->check_element(val))
                g<<"1\n";
            else g<<"0\n";
        }
        else if(op == 2)
        {
            my_hash->remove_element(val);
        }
        else if(op == 1)
        {
            my_hash->insert_element(val);
        }
    }
    f.close();
    g.close();
    delete my_hash;
    my_hash = 0;
    return 0;
}
 
FNV_Hash::FNV_Hash(unsigned int size)
{
    hash_vector             = new vector<int>[size];
    hash_size               = size;
    FNV_prime               = 16777619;
    FNV_init                = 2166136261U;
}
FNV_Hash::~FNV_Hash()
{
    delete []hash_vector;
    hash_vector = 0;
}
unsigned int FNV_Hash::hash_function(int elem)
{
    int last_part, return_value;
 
    for(return_value = FNV_init;elem;elem/=10)
    {
        last_part           = elem%10;
        return_value        = return_value ^ char(last_part + 'a');
        return_value        = return_value * FNV_prime;
    }
    return return_value;
}
 
void FNV_Hash::insert_element(int elem)
{
    unsigned int hash_key       = hash_function(elem) % hash_size;
 
    for(vector<int>::iterator it = hash_vector[hash_key].begin();it!=hash_vector[hash_key].end();++it)
    {
        if(*it == elem)
            return;
    }
    hash_vector[hash_key].push_back(elem);
}
 
void FNV_Hash::remove_element(int elem)
{
    unsigned int hash_key       = hash_function(elem) % hash_size;
 
    for(vector<int>::iterator it = hash_vector[hash_key].begin();it!=hash_vector[hash_key].end();++it)
    {
        if(*it == elem)
        {
            hash_vector[hash_key].erase(it);
            return;
        }
    }
}
 
bool FNV_Hash::check_element(int elem)
{
    unsigned int hash_key       = hash_function(elem) % hash_size;
 
    for(vector<int>::iterator it = hash_vector[hash_key].begin();it!=hash_vector[hash_key].end();++it)
    {
        if(*it == elem)
        {
            return true;
        }
    }
    return false;
}
/*#include <math.h>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#define prim 1000000009
 
using namespace std;
 
class cuckoo_set
{
    int mod;
    int *hash;
    int hash_size;
    int a,b;
    public:
    cuckoo_set(int size)
        {
        hash = new int[size];
        hash_size = size;
        fill(hash,hash+size,0);
        }
 
    int insert(int value)
    {
    int cycles=0,aux=value,which=1;
    bool found=false;
    if (find(value)) return 1;
    while (!found)
                {
                int poz1 = function1(value);
                int poz2 = function2(value);
                cycles++;
                if (hash[poz1] == 0)
                    {
                    hash[poz1] = value;
                    found = true;
                    }
                else if(hash[poz2] == 0)
                    {
                    hash[poz2] = value;
                    found = true;
                    }
                    else
                        {
                        if (which==1)
                            {
                            aux = value;
                            value = hash[poz1];
                            hash[poz1] = aux;
                            }
                        else
                            {
                            aux = value;
                            value = hash[poz2];
                            hash[poz2] = aux;
                            }
                        which*=-1;
                        }
        if ((cycles > log2(this->hash_size))&&(!found)){return 0;}//numarul de incercari nu depaseste log size
    }
    return 1;
    }
 
    void erase(int value)
    {
 
        int poz1 = function1(value);
        int poz2 = function2(value);
        if (hash[poz1] == value)
            {
            hash[poz1] = 0;
            }
        else if (hash[poz2] == value)
            {
            hash[poz2] = 0;
            }
    }
 
    int find(int value)
    {
    int poz1 = function1(value);
    int poz2 = function2(value);
    if (hash[poz1] == value || hash[poz2] == value)
    {
        return 1;
    }
    else
    {
        return 0;
    }
    }
 
    int function1(int value)
    {
        return (((long long)b+(long long)value * (long long)a ) % (long long)prim )% (long long)hash_size;
    }
    int function2(int value)
    {
        return (((long long)a+(long long)value * (long long)b ) % (long long)prim ) %(long long)hash_size;
    }
    void make_hash_function()
    {
         a = rand() % hash_size;
         b = rand() % hash_size;
    }
};
 
int main()
{
 
    bool ok = false,ok2 = true;
    srand(time(0));
    while (ok == false)
    {
 
        ifstream f("hashuri.in");
        ofstream g("hashuri.out");
        cuckoo_set t(1000001);
        int N;
        t.make_hash_function();
        f >> N;
        ok2 = true;
        for (int i =0;i<N && ok2 == true;i++)
        {
            int x , op;
            f >> op >> x;
            if (op == 1)
            {
                if ( !t.insert(x) )
                {
                    ok = false;
                    ok2 = false;
                }
            }
            if (op == 2)
            {
                t.erase(x);
            }
            if (op == 3)
            {
                g << t.find(x) << "\n";
            }
        }
        ok = true;
    }
    return 0;
}
*/