Skip to content
Snippets Groups Projects
Commit 164b4d36 authored by Bouquillon Fabien's avatar Bouquillon Fabien
Browse files

ajout multiset.h

parent 71a11473
Branches
No related tags found
No related merge requests found
all: ucb_etat_de_l_art ucb_categorie exploration_graph
all: install_multiset ucb_etat_de_l_art ucb_categorie exploration_graph
install_multiset:
cp ./include/multiset.h /usr/include/
ucb_etat_de_l_art: initialize_RMB_LMB
$(MAKE) -C UCB_local
......
#ifndef __LIB_MATH_MULTISET__
#define __LIB_MATH_MULTISET__
/**
* \file multiset.hpp
* \author Fabien Bouquillon
* \brief This file contains the namespace Mathset with the class Multiset.
* It proposes some functions to compute Multiset.
* Nowadays the files is not really finished, if use in anormal way the multisets can be corrupt.
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
/**
* \namespace Mathset
* \brief This namespace contains all the functions of this tiny library but also the class Multiset and the structure element
*/
namespace Mathset {
/**
* \struct Element
* \brief This structure represent one or more same element in a multiset.
*/
template <typename T>
struct Element {
/*! The number of this elemennt in the multiset.*/
int counter;
/*! The element, it's a template type */
T elem;
};
/**
*\class Multiset
* \brief It's the class which represent a set or a multiset.
*/
template <typename T>
class Multiset {
private:
std::vector<struct Element<T>> multiset; /*! the actual multiset, a vector of Element. */
public:
/**
* \fn Multiset()
* \prama nothing
* \return nothing
* \brief the default constructor, build a empty multiset.
*/
Multiset() {
}
/**
* \fn Multiset(std::vector<struct Element<T>> multiset)
*\param std::vector<struct Element<T>> multiset, it's a vector of Element
*\return nothing
*\brief Allow the developper to build a non-empty multiset.
*/
Multiset(std::vector<struct Element<T>> multiset) {
this->multiset = multiset;
}
/**
* \fn void add_elem(T elem)
* \param T elem; represents the new element to add
* \return nothing
* \brief jus add a new element in the multiset
*/
void add_elem(T elem) {
for(int i = 0; i < (int)multiset.size(); i++) {
if(multiset[i].elem == elem) {
multiset[i].counter++;
return;
}
}
struct Element<T> e;
e.elem = elem;
e.counter = 1;
multiset.push_back(e);
}
/**
* \fn void rm_elem(T elem)
* \param T elm, the element to remove
* \return nothing
* \brief This function remove an element T of the multiset
*/
void rm_elem(T elem) {
for(int i = 0; i < (int)multiset.size(); i++) {
if(multiset[i].elem == elem) {
multiset[i].counter--;
if(multiset[i].counter <= 0) {
multiset.erase(multiset.begin() + i);
return;
}
}
}
}
/**
* \fn void add_elem_struct(struct Element<T> e)
* \param struct Element<T> e, the element(s) to add
* \return nothing
* \brief add one ore more same element to the multiset
*/
void add_elem_struct(struct Element<T> e) {
if(e.counter <= 0) {
return;
}
for(int i = 0; i < (int)multiset.size(); i++) {
if(multiset[i].elem == e.elem) {
multiset[i].counter += e.counter;
return;
}
}
multiset.push_back(e);
}
/**
* \fn void rm_elem_from_struct(struct Element<T> e)
* \param struct Element<T> e
* \return nothing
* \brief remove one or more same element to the multiset
*/
void rm_elem_from_struct(struct Element<T> e) {
if(e.counter <=0 ) {
return;
}
for(int i = 0; i < (int)multiset.size(); i++) {
if(multiset[i].elem == e.elem) {
multiset[i].counter -= e.counter;
if(multiset[i].counter <= 0) {
multiset.erase(multiset.begin() + i);
return;
}
}
}
}
/**
* \fn void to_set()
* \param nothing
* \return nothing
* \brief Allow the developper to change the multiset into a set
*/
void to_set() {
for(int i = 0; i < (int)multiset.size(); i++) {
multiset[i].counter = 1;
}
}
/**
* \fn std::vector<struct Element<T>> get_multiset()
* \param nothing
* \return std::vector<struct Element<T>>, the multiset of the class
* \brief This function returns the vector which represents the multiset in the class.
*/
std::vector<struct Element<T>> get_multiset() const {
return multiset;
}
std::vector<T> get_set() {
std::vector<T> tmp;
for(int i = 0; i < multiset.size(); i++) {
tmp.push_back(multiset[i].elem);
}
return tmp;
}
void multiply_counter(int n) {
for(int i = 0; i < (int)multiset.size(); i++) {
multiset[i].counter *= n;
}
}
/**
* \fn void print_vector()
* \param nothing
* \return nothing
* \brief This function just print in a human understanding way the multiset in a the std::cout ouput.
*/
void print_vector() {
int sum_t = 0;
for(int i = 0; i < (int)multiset.size(); i++) {
sum_t += multiset[i].counter;
}
std::cout << "multiset of " << sum_t << " elements:" << std::endl;
for(int i = 0; i < (int)multiset.size(); i++) {
for(int j = 0; j < multiset[i].counter; j++) {
std::cout << multiset[i].elem;
if(i != (int)multiset.size() - 1 || j != multiset[i].counter - 1) {
std::cout << ",";
} else {
std::cout << std::endl;
return;
}
}
}
}
void to_string(std::ofstream &f) {
int sum_t = 0;
for(int i = 0; i < (int)multiset.size(); i++) {
sum_t += multiset[i].counter;
}
for(int i = 0; i < (int)multiset.size(); i++) {
for(int j = 0; j < multiset[i].counter; j++) {
f << ( multiset[i].elem);
if(i != (int)multiset.size() - 1 || j != multiset[i].counter - 1) {
f << ",";
} else {
return;
}
}
}
}
/**
* \fn void clear()
* \param nothing
* \return nothing
* \brief remove all the elements in the Multiset
*/
void clear() {
multiset.clear();
}
int size() {
int sum = 0;
for(int i = 0; i < (int) multiset.size(); i++) {
sum += multiset[i].counter;
}
return sum;
}
T elem_max() {
T max = 0;
for(int i = 0; i < (int)multiset.size(); i++) {
if(multiset[i].counter > 0 && max < multiset[i].elem) {
max = multiset[i].elem;
}
}
return max;
}
bool contain(Multiset<T> m) {
std::vector<Element<T>> m_v = m.get_multiset();
for(auto iter_m_v = m_v.begin(); iter_m_v != m_v.end(); iter_m_v++) {
bool not_found = true;
for(auto iter_c = multiset.begin(); iter_c != multiset.end(); iter_c++) {
if(iter_m_v->elem == iter_c->elem) {
not_found = false;
if(iter_m_v->counter > iter_c->elem) {
return false;
}
}
}
if(not_found) {
return false;
}
}
return true;
}
};
/**
* /fn Multiset<T> math_set_union(Multiset<T> a, Multiset<T> b)
* /param Multiset<T> a, the first multiset in the computation, Multiset<T> b, the second multiset in the computation
* /return Multiset<T> it's the multiset compute
* /brief this function compute the Union set operation and return a set
*/
template <typename T>
Multiset<T> math_set_union(Multiset<T> a, Multiset<T> b) {
Multiset<T> tmp(a.get_multiset());
std::vector<struct Element<T>> b_bis = b.get_multiset();
for(int i = 0; i < (int)b_bis.size(); i++) {
tmp.add_elem_struct(b_bis[i]);
}
tmp.to_set();
return tmp;
}
/**
* /fn Multiset<T> math_set_intersection(Multiset<T> a, Multiset<T> b)
* /param Multiset<T> a, the first multiset in the computation, Multiset<T> b, the second multiset in the computation
* /return Multiset<T> it's the multiset compute
* /brief this function compute the Intersection set operation and return a set
*/
template <typename T>
Multiset<T> math_set_intersection(Multiset<T> a, Multiset<T> b) {
std::vector<struct Element<T>> tmp_m;
std::vector<struct Element<T>> a_bis = a.get_multiset();
std::vector<struct Element<T>> b_bis = b.get_multiset();
for(int i = 0; i < (int)a_bis.size(); i++) {
for(int j = 0; j < (int)b_bis.size(); j++) {
if(
(a_bis[i].counter > 0 && b_bis[j].counter > 0) &&
(a_bis[i].elem == b_bis[j].elem)) {
struct Element<T> e;
e.counter = 1;
e.elem = a_bis[i].elem;
tmp_m.push_back(e);
}
}
}
Multiset<T> tmp(tmp_m);
return tmp;
}
/**
* /fn Multiset<T> math_set_minus(Multiset<T> a, Multiset<T> b)
* /param Multiset<T> a, the first multiset in the computation, Multiset<T> b, the second multiset in the computation
* /return Multiset<T> it's the multiset compute
* /brief this function compute the minus set operation (a - b) and return a set
*/
template <typename T>
Multiset<T> math_set_minus(Multiset<T> a, Multiset<T> b) {
std::vector<struct Element<T>> a_bis = a.get_multiset();
std::vector<struct Element<T>> b_bis = b.get_multiset();
for(int i = 0; i < (int)a_bis.size(); i++) {
a_bis[i].counter = 1;
}
for(int i = 0; i < (int)b_bis.size(); i++) {
b_bis[i].counter = 1;
}
Multiset<T> tmp(a_bis);
for(int i = 0; i < (int)b_bis.size(); i++) {
tmp.rm_elem_from_struct(b_bis[i]);
}
return tmp;
}
/**
* /fn Multiset<T> math_multiset_union(Multiset<T> a, Multiset<T> b)
* /param Multiset<T> a, the first multiset in the computation, Multiset<T> b, the second multiset in the computation
* /return Multiset<T> it's the multiset compute
* /brief this function compute the Union multiset operation and return a multiset
*/
template <typename T>
Multiset<T> math_multiset_union(Multiset<T> a, Multiset<T> b) {
Multiset<T> tmp(a.get_multiset());
std::vector<struct Element<T>> b_bis = b.get_multiset();
for(int i = 0; i < (int)b_bis.size(); i++) {
tmp.add_elem_struct(b_bis[i]);
}
return tmp;
}
/**
* /fn Multiset<T> math_multiset_intersection(Multiset<T> a, Multiset<T> b)
* /param Multiset<T> a, the first multiset in the computation, Multiset<T> b, the second multiset in the computation
* /return Multiset<T> it's the multiset compute
* /brief this function compute the Intersection multiset operation and return a set
*/
template <typename T>
Multiset<T> math_multiset_intersection(Multiset<T> a, Multiset<T> b) {
std::vector<struct Element<T>> tmp_m;
std::vector<struct Element<T>> a_bis = a.get_multiset();
std::vector<struct Element<T>> b_bis = b.get_multiset();
for(int i = 0; i < (int)a_bis.size(); i++) {
for(int j = 0; j < (int)b_bis.size(); j++) {
if(
(a_bis[i].counter > 0 && b_bis[j].counter > 0) &&
(a_bis[i].elem == b_bis[j].elem)) {
struct Element<T> e;
e.counter = std::min(a_bis[i].counter, b_bis[j].counter);
e.elem = a_bis[i].elem;
tmp_m.push_back(e);
}
}
}
Multiset<T> tmp(tmp_m);
return tmp;
}
/**
* /fn Multiset<T> math_mutliset_minus(Multiset<T> a, Multiset<T> b)
* /param Multiset<T> a, the first multiset in the computation, Multiset<T> b, the second multiset in the computation
* /return Multiset<T> it's the multiset compute
* /brief this function compute the minus multiset (a - b) operation and return a multiset
*/
template <typename T>
Multiset<T> math_multiset_minus(Multiset<T> a, Multiset<T> b) {
std::vector<struct Element<T>> b_bis = b.get_multiset();
Multiset<T> tmp(a.get_multiset());
for(int i = 0; i < (int)b_bis.size(); i++) {
tmp.rm_elem_from_struct(b_bis[i]);
}
return tmp;
}
/**
* /fn Multiset<T> math_multiset_diff_sym(Multiset<T> a, Multiset<T> b)
* /param Multiset<T> a, the first multiset in the computation, Multiset<T> b, the second multiset in the computation
* /return Multiset<T> it's the multiset compute
* /brief this function compute the symetric difference multiset operation and return a multiset
*/
template <typename T>
Multiset<T> math_multiset_diff_sym(Multiset<T> a, Multiset<T> b) {
return math_multiset_union(math_multiset_minus(a,b), math_multiset_minus(b,a));
}
/**
* /fn Multiset<T> math_multiset_fusion(Multiset<T> a, Multiset<T> b)
* /param Multiset<T> a, the first multiset in the computation, Multiset<T> b, the second multiset in the computation
* /return Multiset<T> it's the multiset compute
* /brief this function compute the fusion multiset operation and return a set
*/
template <typename T>
Multiset<T> math_multiset_fusion(Multiset<T> a, Multiset<T> b) {
return math_multiset_union(math_multiset_diff_sym(a,b), math_multiset_intersection(a,b));
}
template <typename T>
bool operator==(Multiset<T> const& a, Multiset<T> const& b) {
std::vector<struct Element<T>> a_v = a.get_multiset();
std::vector<struct Element<T>> b_v = b.get_multiset();
if(a_v.size() != b_v.size()) {
return false;
}
for(int i = 0; i < a_v.size(); i++) {
bool not_found = true;
for(int j = 0; j < b_v.size(); j++) {
if(b_v[j].elem == a_v[i].elem) {
not_found = false;
if(b_v[j].counter != a_v[i].counter) {
return false;
}
}
}
if(not_found) {
return false;
}
}
return true;
}
template <typename T>
bool operator!=(Multiset<T> const& a, Multiset<T> const& b) {
std::vector<struct Element<T>> a_v = a.get_multiset();
std::vector<struct Element<T>> b_v = b.get_multiset();
if(a_v.size() != b_v.size()) {
return true;
}
for(int i = 0; i < a_v.size(); i++) {
bool not_found = true;
for(int j = 0; j < b_v.size(); j++) {
if(b_v[j].elem == a_v[i].elem) {
not_found = false;
if(b_v[j].counter != a_v[i].counter) {
return true;
}
}
}
if(not_found) {
return true;
}
}
return false;
}
}
#endif // __LIB_MATH_MULTISET__
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment