Cod sursa(job #909495)

Utilizator brainwashed20Alexandru Gherghe brainwashed20 Data 10 martie 2013 15:52:37
Problema Hashuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.79 kb
#include<fstream>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
  
using namespace std;

class hash_function {
	
	private:
	
	int a, b, prime, size;
	
	public:
	
	void generate(int, int);
	int calculate(int);
};

void hash_function::generate(int dim, int p) {
	
	prime = p;
	size = dim;
	
	a = rand() % size;
	b = rand() % size;
}

int hash_function::calculate(int val) {
	return(((long long)a * (long long)val + (long long)b) % (long long)prime) % size;
}
	

template<class T>
class cockooHash {
  
    private:
   
    ifstream f;
    ofstream g;
  
	T *H1, *H2;
	int prime, size, maxsteps;
    bool *viz1, *viz2;
  
	hash_function func1, func2;
  
    public:
  
    cockooHash<T>(int);
    bool remake_hash(string, string);
    bool find(T);
    bool erase(T);
    bool insert(T);
};

int main() {
  
    cockooHash<int> myHash(1100000);
  
    srand(time(0));
  
    bool ok = false;
    while(!ok)
        ok = myHash.remake_hash("hashuri.in", "hashuri.out");
  
    return 0;
}

template<class T>
bool cockooHash<T>::remake_hash(string input, string output) {
  
    int Q, op, val;
    bool ok = true;
	
	f.open(input.c_str());
	g.open(output.c_str());
	
    f>>Q;
    while(Q--) {
        f>>op>>val;
        if(op == 1) {
            if(!find(val)) {
                ok = insert(val);
                if(!ok) {
					f.close(); g.close();
                    return false;
				}
			}
        }
        if(op == 2) {
            if(find(val))
                erase(val);
        }
        if(op == 3) {
            if(find(val) == false)
                g<<0<<"\n";
            else
                g<<1<<"\n";
        }
    }
  
    f.close();
    g.close();
  
    return true;
}
  
template<class T>
cockooHash<T>::cockooHash(int dim) {
	
    size = dim;
    maxsteps = (int)log2(size); 
    prime = 1000000009;
  
    H1 = new T[size];
    H2 = new T[size];
    memset(H1, 0, sizeof(H1));
    memset(H2, 0, sizeof(H2));
  
    viz1 = new bool[size];
    viz2 = new bool[size];
	memset(viz1, 0, sizeof(viz1));
    memset(viz2, 0, sizeof(viz1));    
	
	func1.generate(size, prime);
	func2.generate(size, prime);
}
  
template<class T>
bool cockooHash<T>::find(T val) {
  
    int poz1 = func1.calculate(val);
    int poz2 = func2.calculate(val);
  
    if(H1[poz1] == val && viz1[poz1] == true)
        return true;
    if(H2[poz2] == val && viz2[poz2] == true)
        return true;
  
    return false;
}

template<class T>
bool cockooHash<T>::erase(T val) {
  
    int poz1 = func1.calculate(val);
    int poz2 = func2.calculate(val);
  
    if(H1[poz1] == val && viz1[poz1] == true) {
		H1[poz1] = 0;
        viz1[poz1] = false;
        return true;
    }
  
    if(H2[poz2] == val && viz2[poz2] == true) {
        H2[poz2] = 0;
		viz2[poz2] = false;
        return true;
    }
  
    return false;
}

template<class T>
bool cockooHash<T>::insert(T val) {
  
    int i, poz1, poz2;
	T x;
	
    x = val;
    poz1 = func1.calculate(x);
    poz2 = func2.calculate(x);
  
  
    if(viz1[poz1] == false) {
        H1[poz1] = x;
        viz1[poz1] = true;
        return true;
    }
  
    for(i=0; i<maxsteps; i+=2) {
        if(viz2[poz2] == false) {
            H2[poz2] = x;
            viz2[poz2] = true;
            return true;
        }
  
        swap(x, H2[poz2]);
		poz1 = func1.calculate(x);
		poz2 = func2.calculate(x);
  
        if(viz1[poz1] == false) {
            H1[poz1] = x;
            viz1[poz1] = true;
            return true;
        }
  
        swap(x, H1[poz1]);
        poz1 = func1.calculate(x);
		poz2 = func2.calculate(x);    
	}
  
    //e nevoie de rehash daca ajungem aici
    return false;
}