Pagini recente » Cod sursa (job #1552756) | Cod sursa (job #2960482) | Cod sursa (job #1136490) | Cod sursa (job #1177919) | Cod sursa (job #282003)
Cod sursa(job #282003)
#include <iostream>
#include <fstream>
#include <list>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;
typedef unsigned char byte;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned long long ulonglong;
#define NDEBUG
#ifdef NDEBUG
#define dbg 0 && (*((ostream *) 0))
#else
#define dbg clog
#endif
template<class T> class LinkedList;
template<class T>
class ListNode {
public:
ListNode(T data = T(), ListNode * next = 0)
: _data(data), _next(next) {
}
const ListNode<T> * next() const { return _next; }
T data() const { return _data; }
public:
friend class LinkedList<T>;
private:
T _data;
ListNode * _next;
};
template<class T>
class LinkedList {
public:
LinkedList()
: _head(new ListNode<T>()), _tail(_head), _size(0)
{}
public:
void append(T data) {
ListNode<T> * newNode = new ListNode<T>(data);
_tail->_next = newNode;
_tail = newNode;
_size++;
}
bool find(T data) const {
ListNode<T> * traveler = _head->_next;
while(traveler) {
if(data == traveler->_data) {
return true;
}
traveler = traveler->_next;
}
return false;
}
bool erase(T data) {
ListNode<T> * traveler = _head->_next, * previous = _head;
while(traveler) {
if(data == traveler->_data) {
if(traveler == _tail) {
_tail = previous;
}
previous->_next = traveler->_next;
_size--;
delete traveler;
return true;
}
previous = traveler;
traveler = traveler->_next;
}
return false;
}
ulong size() const { return _size; }
public:
friend ostream& operator << (ostream& out, const LinkedList<T>& list) {
const ListNode<T> * traveler = list._head->next();
out << "Linked list of size " << list._size << ": ";
while(traveler) {
out << traveler->data() << " ";
traveler = traveler->next();
}
return out;
}
private:
//ListNode<T> * getTravelerToEnd() { return _tail; }
private:
ListNode<T> * _head;
ListNode<T> * _tail;
ulong _size;
};
namespace Global {
const ulong hashPrime1 = 600001;
const ulong hashPrime2 = 393241;
ulong random;
LinkedList<ulong> hashList1[hashPrime1];
LinkedList<ulong> hashList2[hashPrime2];
inline ulong hashNumber(ulong number, ulong prime) {
return (number * random) % prime;
}
}
class HashTable {
public:
HashTable(LinkedList<ulong> * hashTable, ulong prime)
: _hashTable(hashTable), _hashPrime(prime)
{
}
public:
// Adds the value to the list, returns false if the value is already in the list, and false otherwise
void add(ulong value) {
ulong hash = Global::hashNumber(value, _hashPrime);
if(!_hashTable[hash].find(value)) {
_hashTable[hash].append(value);
}
}
bool find(ulong value) {
ulong hash = Global::hashNumber(value, _hashPrime);
return _hashTable[hash].find(value);
}
bool erase(ulong value) {
ulong hash = Global::hashNumber(value, _hashPrime);
return _hashTable[hash].erase(value);
}
public:
friend ostream& operator << (ostream& out, const HashTable& hashTable) {
out << "HashTable Modulo " << hashTable._hashPrime << endl;
for(uint i = 0; i < hashTable._hashPrime; i++) {
if(hashTable._hashTable[i].size()) {
out << "List Modulo " << i << " | " << hashTable._hashTable[i] << endl;
}
}
return out;
}
public:
ulong getHashPrime() const { return _hashPrime; }
LinkedList<ulong> * getLinkedList() { return _hashTable; }
private:
LinkedList<ulong> * _hashTable;
ulong _hashPrime;
};
class DoubleHashTableManager {
public:
DoubleHashTableManager(HashTable& first, HashTable& second)
: _first(first), _second(second)
{
_firstHashPrime = _first.getHashPrime();
_firstHashTable = _first.getLinkedList();
_secondHashPrime = _second.getHashPrime();
_secondHashTable = _second.getLinkedList();
}
public:
void add(ulong value) {
ulong firstHash = Global::hashNumber(value, _firstHashPrime);
ulong secondHash = Global::hashNumber(value, _secondHashPrime);
if(!_firstHashTable[firstHash].find(value) && !_secondHashTable[secondHash].find(value)) {
if(_firstHashTable[firstHash].size() < _secondHashTable[secondHash].size()) {
_firstHashTable[firstHash].append(value);
} else {
_secondHashTable[secondHash].append(value);
}
}
}
bool find(ulong value) {
ulong firstHash = Global::hashNumber(value, _firstHashPrime);
ulong secondHash = Global::hashNumber(value, _secondHashPrime);
if(_firstHashTable[firstHash].find(value))
return true;
if(_secondHashTable[secondHash].find(value))
return true;
return false;
}
bool erase(ulong value) {
ulong firstHash = Global::hashNumber(value, _firstHashPrime);
ulong secondHash = Global::hashNumber(value, _secondHashPrime);
if(_firstHashTable[firstHash].erase(value))
return true;
if(_secondHashTable[secondHash].erase(value))
return true;
return false;
}
private:
HashTable& _first;
HashTable& _second;
LinkedList<ulong> * _firstHashTable, * _secondHashTable;
ulong _firstHashPrime, _secondHashPrime;
};
void testLinkedList() {
LinkedList<ulong> newList;
ulong vect[] = {4, 10, 5, 11};
ulong size = sizeof(vect)/sizeof(vect[0]);
for(uint i = 0; i < size; i++) {
newList.append(vect[i]);
}
cout << newList << endl;
for(uint i = 0; i < size; i++) {
cout << "Found " << vect[i] << ": " << newList.find(vect[i]) << endl;
}
for(uint i = 0; i < size; i++) {
ulong toFind = vect[i]*4;
cout << "Found " << toFind << ": " << newList.find(toFind) << endl;
}
for(uint i = 0; i < size; i++) {
if(vect[i]%2 == 1) {
newList.erase(vect[i]);
}
}
cout << newList << endl;
for(uint i = 0; i < size; i++) {
newList.append(vect[i]);
}
cout << newList << endl;
}
int main(int argc, char * argv[]) {
#ifndef NDEBUG
testLinkedList();
#endif
srand(time(0));
Global::random = rand() % 770;
const char * inFile = "hashuri.in";
const char * outFile = "hashuri.out";
ifstream fin(inFile);
ofstream fout(outFile);
#ifndef NDEBUG
if(!fin || !fout) {
cerr << "Error opening one of \"" << inFile << "\" or \"" << outFile << "\"" << endl;
return -1;
}
#endif
ulong n, operation, param;
fin >> n;
HashTable hashTable1(Global::hashList1, Global::hashPrime1);
HashTable hashTable2(Global::hashList2, Global::hashPrime2);
DoubleHashTableManager hashTable(hashTable1, hashTable2);
for(ulong i = 0; i < n; i++) {
fin >> operation >> param;
switch(operation) {
case 1:
hashTable.add(param);
break;
case 2:
hashTable.erase(param);
break;
case 3:
fout << static_cast<ulong>(hashTable.find(param)) << endl;
break;
}
}
fout.close();
fin.close();
return 0;
}