Cod sursa(job #2416038)

Utilizator horiacoolNedelcu Horia Alexandru horiacool Data 26 aprilie 2019 20:13:54
Problema Hashuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.01 kb
#include <fstream>

#ifndef HASHTABLE_H_
#define HASHTABLE_H_

#include <list>
#include <iterator>
#include <iostream>

/**
 * Hashtable implementation.
 */
template <typename Tkey, typename Tvalue> struct info {
    Tkey key;
    Tvalue value;
};

template <typename Tkey, typename Tvalue> class Hashtable {
 private:
    std::list<struct info<Tkey, Tvalue>> *H_;
    int size_;
    int capacity_;
    int (*hash_)(Tkey);

 public:
    Hashtable(int capacity, int (*h)(Tkey));

    Hashtable(const Hashtable<Tkey, Tvalue>&);

    ~Hashtable();

    Hashtable<Tkey, Tvalue>& operator=(const Hashtable<Tkey, Tvalue>&);

    void put(Tkey key, Tvalue value);

    void remove(Tkey key);

    Tvalue operator[](Tkey key);

    bool has_key(Tkey key);

    int get_size();

    int get_capacity();
};

template <typename Tkey, typename Tvalue>
Hashtable<Tkey, Tvalue>::Hashtable(int capacity, int (*h)(Tkey)):
    H_(nullptr), size_(0), capacity_(capacity), hash_(h) {
    try {
        H_ = new std::list<struct info<Tkey, Tvalue>>[capacity];
    } catch (std::exception& e) {
        std::cerr << "Standard exception: " << e.what() << '\n';
    }
}

template <typename Tkey, typename Tvalue>
Hashtable<Tkey, Tvalue>::Hashtable(const Hashtable<Tkey, Tvalue>& other) {
    try {
        H_ = new std::list<struct info<Tkey, Tvalue>>[other.capacity];
    } catch (std::exception& e) {
        std::cerr << "Standard exception: " << e.what() << '\n';
    }

    for (int i = 0; i < other.capacity; ++i) {
        H_[i] = other.H_[i];
    }

    size_ = other.size_;
    capacity_ = other.capacity_;
    hash_ = other.hash_;
}

template <typename Tkey, typename Tvalue>
Hashtable<Tkey, Tvalue>::~Hashtable() {
    delete[] H_;
}

template <typename Tkey, typename Tvalue> Hashtable<Tkey, Tvalue>&
Hashtable<Tkey, Tvalue>::operator=(const Hashtable<Tkey, Tvalue>& other) {
    delete[] H_;

    try {
        H_ = new std::list<struct info<Tkey, Tvalue>>[other.capacity];
    } catch (std::exception& e) {
        std::cerr << "Standard exception: " << e.what() << '\n';
    }

    for (int i = 0; i < other.capacity; ++i) {
        H_[i] = other.H_[i];
    }

    size_ = other.size_;
    capacity_ = other.capacity_;
    hash_ = other.hash_;
}

template <typename Tkey, typename Tvalue>
void Hashtable<Tkey, Tvalue>::put(Tkey key, Tvalue value) {
    info<Tkey, Tvalue> data = {key, value};

    remove(key);
    H_[hash_(key) % capacity_].push_back(data);
}

template <typename Tkey, typename Tvalue>
void Hashtable<Tkey, Tvalue>::remove(Tkey key) {
    int index = hash_(key) % capacity_;

    for (auto it = H_[index].begin(); it != H_[index].end(); ++it) {
        if ((*it).key == key) {
            H_[index].erase(it);
            break;
        }
    }
}

template <typename Tkey, typename Tvalue>
Tvalue Hashtable<Tkey, Tvalue>::operator[](Tkey key) {
    int index = hash_(key) % capacity_;

    for (auto it = H_[index].begin(); it != H_[index].end(); ++it) {
        if ((*it).key == key) {
            return (*it).value;
        }
    }

    std::cerr << "Standard exception: key not found\n";
    return Tvalue();
}

template <typename Tkey, typename Tvalue>
bool Hashtable<Tkey, Tvalue>::has_key(Tkey key) {
    int index = hash_(key) % capacity_;

    for (auto it = H_[index].begin(); it != H_[index].end(); ++it) {
        if ((*it).key == key) {
            return true;
        }
    }

    return false;
}

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

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

#endif // HASHTABLE_H_

int int_hash(int number) {
  return number;
}

int main() {
	std::ifstream fin("hashuri.in");
	std::ofstream fout("hashuri.out");

	Hashtable<int, int> ht(666013, int_hash);
	int N, q, x;

	fin >> N;
	for (int i = 0; i < N; ++i) {
		fin >> q >> x;

		switch(q) {
			case 1:
				ht.put(x, 1);
				break;
			case 2:
				ht.remove(x);
				break;
			default:
				fout << ht.has_key(x) << '\n';
		}
	}

	fin.close();
	fout.close();

	return 0;
}