Cod sursa(job #906971)

Utilizator brainwashed20Alexandru Gherghe brainwashed20 Data 7 martie 2013 15:09:52
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 4.04 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, limit;
    unsigned prime;
    int a1, b1, a2, b2;
    bool *viz1, *viz2;
 
    void make_hash_function(int&, int&);
    int hash1(int);
    int hash2(int);
    void rehash();
 
    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;
    
    f>>Q;
    while(Q--) {
        f>>op>>val;
        if(op == 1) {
            if(!find(val))
                ok = insert(val);
                if(!ok)
                    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;
}
 
int main() {
 
    cockooHash myHash(1000000, "hashuri.in", "hashuri.out");
 
    srand(time(0));
 
    bool ok;
 
    ok = false;
    while(!ok)
        ok = myHash.remake_hash();
 
    return 0;
}
 
cockooHash::cockooHash(int size, string input, string output) {
    
    f.open(input.c_str());
    g.open(output.c_str());
    
    this->size = size;
    this->limit = (int)log2(size); // vom scoate maxim log2(size) elemente din hash
    this->prime = 1000000009;
 
    this->H1 = new int[size];
    this->H2 = new int[size];
    memset(this->H1, 0, sizeof(this->H1));
    memset(this->H2, 0, sizeof(this->H2));
 
    this->viz1 = new bool[size];
    this->viz2 = new bool[size];
    memset(this->viz1, 0, sizeof(this->viz1));
    memset(this->viz2, 0, sizeof(this->viz1));
 
    rehash();
}
 
bool cockooHash::find(int val) {
 
    int poz1 = this->hash1(val);
    int poz2 = this->hash2(val);
 
    if(this->H1[poz1] == val && this->viz1[poz1] == true)
        return true;
    if(this->H2[poz2] == val && this->viz2[poz2] == true)
        return true;
 
    return false;
}
 
bool cockooHash::erase(int val) {
 
    int poz1 = this->hash1(val);
    int poz2 = this->hash2(val);
 
    if(this->H1[poz1] == val && this->viz1[poz1] == true) {
        this->viz1[poz1] = false;
        return true;
    }
 
    if(this->H2[poz2] == val && this->viz2[poz2] == true) {
        this->viz2[poz2] = false;
        return true;
    }
 
    return false;
}
 
bool cockooHash::insert(int val) {
 
    int i, x, poz1, poz2;
 
    x = val;
    poz1 = this->hash1(x);
    poz2 = this->hash2(x);
 
    if(this->viz1[poz1] == false) {
        this->H1[poz1] = x;
        this->viz1[poz1] = true;
        return true;
    }
 
    for(i=0; i<limit; i+=2) {
        if(this->viz2[poz2] == false) {
            this->H2[poz2] = x;
            this->viz2[poz2] = true;
            return true;
        }
 
        swap(x, this->H2[poz2]);
        poz1 = this->hash1(x);
        poz2 = this->hash2(x);
 
        if(this->viz1[poz1] == false) {
            this->H1[poz1] = x;
            this->viz1[poz1] = true;
            return true;
        }
 
        swap(x, this->H1[poz1]);
        poz1 = this->hash1(x);
        poz2 = this->hash2(x);
    }
 
    //e nevoie de rehash daca ajungem aici
    return false;
}
 
void cockooHash::make_hash_function(int &a, int &b) {
        a = rand() % this->size;
        b = rand() % this->size;
}
 
int cockooHash::hash1(int val) {
    return(((long long)this->a1 * (long long)val + (long long)this->b1) % (long long)this->prime) % this->size;
}
 
int cockooHash::hash2(int val) {
    return(((long long)this->a2 * (long long)val + (long long)this->b2) % (long long)this->prime) % this->size;
}
 
void cockooHash::rehash() {
    make_hash_function(this->a1, this->b1);
    make_hash_function(this->a2, this->b2);
}