Cod sursa(job #908876)

Utilizator cdascaluDascalu Cristian cdascalu Data 10 martie 2013 09:54:06
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 4.29 kb
//Pentru detalii:
//http://stackoverflow.com/a/98179
//http://www.isthe.com/chongo/tech/comp/fnv/
//(numerele sunt siruri de caractere)
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#define Nmax 699967
using namespace std;

template <class Type>
class FNV_Hash
{
    public:

        FNV_Hash(unsigned int);
        ~FNV_Hash();

        unsigned int       hash_function(Type);
        void                insert_element(Type);
        void                remove_element(Type);
        bool                check_element(Type);
        string              convert_element(Type);
        string&             convert_element(Type, string&);
    private:

        unsigned int             hash_size;
        unsigned int             FNV_prime;
        unsigned int             FNV_init;

        vector<Type>               *hash_vector;
};
int main()
{
    FNV_Hash<int> *my_hash;
    my_hash = new FNV_Hash<int>(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;
}

//==========================================================================

template<class Type>
FNV_Hash< Type >::FNV_Hash(unsigned int size)
{
    hash_vector             = new vector<Type>[size];
    hash_size               = size;
    FNV_prime               = 16777619;
    FNV_init                = 2166136261U;
}

//==========================================================================

template<class Type>
FNV_Hash< Type >::~FNV_Hash()
{
    delete []hash_vector;
    hash_vector = 0;
}

//==========================================================================

template<class Type>
string FNV_Hash< Type>::convert_element(Type elem)
{
    ostringstream   stream;
    stream<<elem;
    return stream.str();
}

//==========================================================================

template<class Type>
string& FNV_Hash< Type>::convert_element(Type elem, string& my_string)
{
    ostringstream   stream;
    stream<<elem;
    my_string = stream.str();
    return my_string;
}

//==========================================================================

template<class Type>
unsigned int FNV_Hash< Type >::hash_function(Type elem)
{
    string good_elem;

    good_elem = convert_element(elem, good_elem);

    unsigned int return_value;
    char last_part;
    unsigned int i=0,size = good_elem.size();;

    for(return_value = FNV_init;i<size;++i)
    {
        last_part           = good_elem[i];
        return_value        = return_value ^ char(last_part);
        return_value        = return_value * FNV_prime;
    }
    return return_value;
}

//==========================================================================

template<class Type>
void FNV_Hash<Type>::insert_element(Type elem)
{
    unsigned int hash_key       = hash_function(elem) % hash_size;

    for(typename vector<Type>::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);
}

//==========================================================================

template<class Type>
void FNV_Hash<Type>::remove_element(Type elem)
{
    unsigned int hash_key       = hash_function(elem) % hash_size;

    for(typename vector<Type>::iterator it = hash_vector[hash_key].begin();it!=hash_vector[hash_key].end();++it)
    {
        if(*it == elem)
        {
            hash_vector[hash_key].erase(it);
            return;
        }
    }
}

//==========================================================================

template<class Type>
bool FNV_Hash<Type>::check_element(Type elem)
{
    unsigned int hash_key       = hash_function(elem) % hash_size;

    for(typename vector<Type>::iterator it = hash_vector[hash_key].begin();it!=hash_vector[hash_key].end();++it)
    {
        if(*it == elem)
        {
            return true;
        }
    }
    return false;
}