Cod sursa(job #908285)

Utilizator brainwashed20Alexandru Gherghe brainwashed20 Data 9 martie 2013 00:11:12
Problema Hashuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 3.84 kb
#include<fstream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<ctime>
#include<string>
  
using namespace std;
  
class cockooHash {
  
    private:
   
    ifstream f;
    ofstream g;
  
    int *H1, *H2, size, maxsteps;
    unsigned prime;
    int a1, b1, a2, b2;
    bool *viz1, *viz2;
  
    void generate_numbers(int&, int&);
    int hash_function1(int);
    int hash_function2(int);
    void generate_hash_functions();
  
    public:
  
    cockooHash(int, string, string);
    bool remake_hash();
    bool find(int);
    bool erase(int);
    bool insert(int);
};
  
bool cockooHash::remake_hash() {
  
    int Q, op, val;
    bool ok = true;
     
    f>>Q;
    while(Q--) {
        f>>op>>val;
        if(op == 1) {
            ok = insert(val);
			if(!ok) {
				f.close(); 
				g.close();
				return false;
			}
		}
        if(op == 2) 
			erase(val);
        if(op == 3) {
            if(find(val) == false)
                g<<0<<"\n";
            else
                g<<1<<"\n";
        }
    }
  
    f.close();
    g.close();
  
    return true;
}
  
int main() {
  
    cockooHash myHash(1000000, "hashuri.in", "hashuri.out");
  
    srand(time(0));
  
    bool ok = false;
    while(!ok)
        ok = myHash.remake_hash();
  
    return 0;
}
  
cockooHash::cockooHash(int dim, string input, string output) {
     
    f.open(input.c_str());
    g.open(output.c_str());
     
    size = dim;
    maxsteps = (int)log2(size); // vom scoate maxim log2(size) elemente din hash
    prime = 1000000009;
  
    H1 = new int[size];
    H2 = new int[size];
    fill(H1, H1+size, 0);
	fill(H2, H2+size, 0);
  
    viz1 = new bool[size];
    viz2 = new bool[size];
    fill(viz1, viz1+size, false);
    fill(viz2, viz2+size, false);
  
    generate_hash_functions();
}
  
bool cockooHash::find(int val) {
  
    int poz1 = hash_function1(val);
    int poz2 = hash_function2(val);
  
    if(H1[poz1] == val && viz1[poz1] == true)
        return true;
    if(H2[poz2] == val && viz2[poz2] == true)
        return true;
  
    return false;
}
  
bool cockooHash::erase(int val) {
  
    int poz1 = hash_function1(val);
    int poz2 = hash_function2(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;
}
  
bool cockooHash::insert(int val) {
  
    int i, x, poz1, poz2;
  
    x = val;
    poz1 = hash_function1(x);
    poz2 = hash_function2(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 = hash_function1(x);
        poz2 = hash_function2(x);
  
        if(viz1[poz1] == false) {
            H1[poz1] = x;
            viz1[poz1] = true;
            return true;
        }
  
        swap(x, H1[poz1]);
        poz1 = hash_function1(x);
        poz2 = hash_function2(x);
    }
  
    //e nevoie de rehash daca ajungem aici
    return false;
}
  
void cockooHash::generate_numbers(int &a, int &b) {
        a = rand() % size;
        b = rand() % size;
}
  
int cockooHash::hash_function1(int val) {
    return(((long long)a1 * (long long)val + (long long)b1) % (long long)prime) % size;
}
  
int cockooHash::hash_function2(int val) {
    return(((long long)a2 * (long long)val + (long long)b2) % (long long)prime) % size;
}
  
void cockooHash::generate_hash_functions() {
    generate_numbers(a1, b1);
    generate_numbers(a2, b2);
}