Cod sursa(job #2417871)

Utilizator horiacoolNedelcu Horia Alexandru horiacool Data 1 mai 2019 23:30:00
Problema Hashuri Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.65 kb
#include <fstream>

#ifndef HASHTABLE_OPEN_ADDRESSING_LAZY_DELETION_H
#define HASHTABLE_OPEN_ADDRESSING_LAZY_DELETION_H

#include <iostream>
#include <vector>
#define ULL unsigned long long int
#define PRIME_CAPACITY_FOR_HASH 666013

enum SlotType {Empty, Occupied, Lazy_Delete};

template <typename Tkey, typename Tvalue>
struct info {
    Tkey key;
    Tvalue value;
};

template <typename Tkey, typename Tvalue>
class Hashtable_OALD {
    private:
        std::vector<struct info<Tkey, Tvalue>> hash_table_;
        std::vector<SlotType> slot_;
        int size_;
        int capacity_;
        ULL (*hash_)(Tkey);

    public:
        Hashtable_OALD(int capacity, ULL (*h)(Tkey));
        ~Hashtable_OALD();
        int findSlotInsert(const Tkey&);
        int findSlotSearch(const Tkey&);
        bool lookup(const Tkey&);
        void set(const Tkey&, const Tvalue&);
        void remove(const Tkey&);
        Tvalue operator[](const Tkey&);
        int getSize();
        int getCapacity();

        void printHashTable();
};

template <typename Tkey, typename Tvalue>
Hashtable_OALD<Tkey, Tvalue>::Hashtable_OALD(int capacity, ULL (*h)(Tkey)):
    hash_table_(capacity), slot_(capacity, SlotType::Empty),
    size_(0), capacity_(capacity), hash_(h) {}

template <typename Tkey, typename Tvalue>
Hashtable_OALD<Tkey, Tvalue>::~Hashtable_OALD() {}

template <typename Tkey, typename Tvalue>
int Hashtable_OALD<Tkey, Tvalue>::findSlotInsert(const Tkey& key) {
    int i = hash_(key) % capacity_;

    // search until we either find the key, or find an empty slot.
    while (slot_[i] == SlotType::Occupied && hash_table_[i].key != key) {
        i = (i + 1) % capacity_;
    }

    // Cases found: Empty slot, Lazy_Delete slot, slot[i].key == key
    return i;
}

template <typename Tkey, typename Tvalue>
int Hashtable_OALD<Tkey, Tvalue>::findSlotSearch(const Tkey& key) {
    int i = hash_(key) % capacity_;

    // search until we either find the key, or find an empty slot.
    while (slot_[i] != SlotType::Empty && hash_table_[i].key != key) {
        i = (i + 1) % capacity_;
    }

    // Cases found: Empty slot (passed all Occupied and Lazy_Delet slots), slot[i].key == key
    return i;
}

template <typename Tkey, typename Tvalue>
bool Hashtable_OALD<Tkey, Tvalue>::lookup(const Tkey& key) {
    int i = findSlotSearch(key);

    if (slot_[i] == SlotType::Occupied) {  // key is in table
        return true;
    }
    else {                                 // key is not in table
        return false;
    }
}

template <typename Tkey, typename Tvalue>
void Hashtable_OALD<Tkey, Tvalue>::set(const Tkey& key, const Tvalue& value) {
    int i = findSlotInsert(key);

    hash_table_[i].key = key;
    hash_table_[i].value = value;
    slot_[i] = SlotType::Occupied;
}

template <typename Tkey, typename Tvalue>
void Hashtable_OALD<Tkey, Tvalue>::remove(const Tkey& key) {
    int i = findSlotInsert(key);
     
    if (slot_[i] == SlotType::Occupied) { // key is in the table
        slot_[i] = SlotType::Lazy_Delete;
    }
}

template <typename Tkey, typename Tvalue>
Tvalue Hashtable_OALD<Tkey, Tvalue>::operator[](const Tkey& key) {
    int i = findSlotSearch(key);

    if (slot_[i] == SlotType::Occupied) {  // key is in table
        return hash_table_[i].value;
    }
    else {                                 // key is not in table
        return Tvalue();
    }
}

template <typename Tkey, typename Tvalue>
int Hashtable_OALD<Tkey, Tvalue>::getSize() {
    return size_;
}

template <typename Tkey, typename Tvalue>
int Hashtable_OALD<Tkey, Tvalue>::getCapacity() {
    return capacity_;
}

template <typename Tkey, typename Tvalue>
void Hashtable_OALD<Tkey, Tvalue>::printHashTable() {
    for (unsigned int i = 0; i < hash_table_.size(); ++i) {
        if (slot_[i] == SlotType::Occupied) {
            std::cout << "<" << i << ", " << hash_table_[i].key << ", " << hash_table_[i].value << "> ";
        }
    }
    std::cout << '\n';

    for (unsigned int i = 0; i < slot_.size(); ++i) {
        std::cout << slot_[i] << ' ';
    }
    std::cout << "\n\n";
}

#endif // HASHTABLE_OPEN_ADDRESSING_LAZY_DELETION_H
 
unsigned long long int int_hash(int number) {
    unsigned long long int hash = 5381;

    while (number) {
        hash = hash * 33 ^ (number % 10);
        number /= 10;
    }

    return hash;
}
 
int main() {
	std::ifstream fin("hashuri.in");
	std::ofstream fout("hashuri.out");
 
	Hashtable_OALD<int, int> ht(PRIME_CAPACITY_FOR_HASH, int_hash);
	int N, q, x;
 
	fin >> N;
	for (int i = 0; i < N; ++i) {
		fin >> q >> x;
 
		switch(q) {
			case 1:
				ht.set(x, 1);
				break;
			case 2:
				ht.remove(x);
				break;
			default:
				fout << ht.lookup(x) << '\n';
		}
	}
 
	fin.close();
	fout.close();
 
	return 0;
}