153 lines
5.4 KiB
C++
Executable File
153 lines
5.4 KiB
C++
Executable File
#pragma once
|
|
#include <queue>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <ostream>
|
|
|
|
namespace Utils {
|
|
/**
|
|
* Wrapper-Klasse um Vergleiche unabhaengig von value zu ermoeglichen
|
|
*
|
|
* \tparam[in] _CompareValueTyupe Typ der compareValue
|
|
* \tparam[in] _ValueType Typ der value
|
|
*/
|
|
template<class _CompareValueTyupe, class _ValueType>
|
|
class CompareContainer {
|
|
public:
|
|
_CompareValueTyupe compareValue;
|
|
_ValueType value;
|
|
|
|
/**
|
|
* Konstruktor
|
|
*
|
|
* \param[in] compareValue Anhand dieser Variable wird verglichen
|
|
* \param[in] value Variable fuer die ein Vergleich benoetigt wird
|
|
*/
|
|
CompareContainer(_CompareValueTyupe compareValue, _ValueType value) : compareValue{compareValue}, value{value} {
|
|
}
|
|
|
|
/**
|
|
* Vergleicht zwei CompareContainer
|
|
*
|
|
* \param[in] other Container 2
|
|
* \return true, wenn die compareValue von this und other gleich ist. Ansonsten false
|
|
*/
|
|
bool operator==(const CompareContainer &other) const { return compareValue == other.compareValue; }
|
|
|
|
/**
|
|
* Vergleicht zwei CompareContainer
|
|
*
|
|
* \param[in] other Container 2
|
|
* \return true, wenn die compareValue von this und other ungleich ist. Ansonsten false
|
|
*/
|
|
bool operator!=(const CompareContainer &other) const { return !this->operator==(other); }
|
|
|
|
/**
|
|
* Vergleicht zwei CompareContainer
|
|
*
|
|
* \param[in] other Container 2
|
|
* \return true, wenn die compareValue von this kleiner als die von other ist. Ansonsten false
|
|
*/
|
|
bool operator<(const CompareContainer &other) const { return compareValue < other.compareValue; }
|
|
|
|
/**
|
|
* Vergleicht zwei CompareContainer
|
|
*
|
|
* \param[in] other Container 2
|
|
* \return true, wenn die compareValue von this groesser als die von other ist. Ansonsten false
|
|
*/
|
|
bool operator>(const CompareContainer &other) const {
|
|
return !this->operator<(other) && !this->operator==(other);
|
|
}
|
|
|
|
/**
|
|
* Vergleicht zwei CompareContainer
|
|
*
|
|
* \param[in] other Container 2
|
|
* \return true, wenn die compareValue von this kleiner oder gleich, wie die von other ist. Ansonsten false
|
|
*/
|
|
bool operator<=(const CompareContainer &other) const { return !this->operator>(other); }
|
|
|
|
/**
|
|
* Vergleicht zwei CompareContainer
|
|
*
|
|
* \param[in] other Container 2
|
|
* \return true, wenn die compareValue von this groesser oder gleich, wie die von other ist. Ansonsten false
|
|
*/
|
|
bool operator>=(const CompareContainer &other) const { return !this->operator<(other); }
|
|
};
|
|
|
|
/**
|
|
* Wrapper-Klasse um die Funktionsweise der std::priority_queue zu erweitern. Ermoeglicht es Objekte mit einem unabhaengigen Gewicht in die pq zu laden und erweitert die pq mit weiteren Methoden.
|
|
* Das kleinste Gewicht ist immer an Position top()
|
|
*
|
|
* \tparam[in] _Tr Datentyp der PriorityQueue
|
|
*/
|
|
template<typename _Tr>
|
|
class PriorityQueue : public std::priority_queue<CompareContainer<double, _Tr>, std::vector<CompareContainer<double,
|
|
_Tr> >, std::greater<CompareContainer<double, _Tr> > > {
|
|
public:
|
|
/**
|
|
* Fuegt ein item mit dem Gewicht weight zur pq hinzu.
|
|
*
|
|
* \param[in] item Objekt was zur pq hinzugefuegt werden soll
|
|
* \param[in] weight Das Gewicht mit dem item priorisiert werden soll
|
|
*/
|
|
void push(_Tr item, double weight) {
|
|
std::priority_queue<CompareContainer<double, _Tr>, std::vector<CompareContainer<double, _Tr> >, std::greater
|
|
<CompareContainer<double, _Tr> > >::push(CompareContainer<double, _Tr>(weight, item));
|
|
}
|
|
|
|
/**
|
|
* Gibt das Item an Position top() zurueck und entfernt dieses aus der pq.
|
|
*
|
|
* \return Item an Position top()
|
|
*/
|
|
_Tr pop_top() {
|
|
_Tr item = this->top().value;
|
|
this->pop();
|
|
return item;
|
|
}
|
|
|
|
/**
|
|
* Entfernt element aus der pq und gibt zurueck, ob es gefunden und entfernt wurde.
|
|
*
|
|
* \return true, wenn element aus der pq entfernt wurde, sonst false
|
|
*/
|
|
bool remove(const _Tr &element) {
|
|
for (auto it = this->c.begin(); it != this->c.end(); it++) {
|
|
if ((*it).value == element) {
|
|
this->c.erase(it);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Sucht nach element in der pq und gibt zurueck ob es gefunden wurde
|
|
*
|
|
* \return true, wenn element in der pq gefunden wurde, sonst false
|
|
*/
|
|
bool contains(const _Tr &element) {
|
|
for (auto it = this->c.begin(); it != this->c.end(); it++) {
|
|
if ((*it).value == element) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Tauscht das Gewicht von element aus und gibt zurueck ob es gefunden wurde.
|
|
*
|
|
* \return true, wenn element in der pq gefunden wurde, sonst false
|
|
*/
|
|
bool change(const _Tr &element, double weight) {
|
|
if (!remove(element)) return false;
|
|
this->push(element, weight);
|
|
return true;
|
|
}
|
|
};
|
|
}
|