La structure de données d'ensemble C++ STL a-t-elle un opérateur de différence d'ensemble?
Oui, il est dans <algorithm>
et s'appelle: std::set_difference
. L'utilisation est:
#include <algorithm>
#include <set>
#include <iterator>
// ...
std::set<int> s1, s2;
// Fill in s1 and s2 with values
std::set<int> result;
std::set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(),
std::inserter(result, result.end()));
En fin de compte, la variable result
contiendra le s1-s2
.
Oui, il existe une fonction set_difference dans l'en-tête de l'algorithme.
Edits:
Pour votre information, la structure de données d'ensemble est capable d'utiliser efficacement cet algorithme, comme indiqué dans sa documentation . L'algorithme fonctionne également non seulement sur les ensembles, mais sur toute paire d'itérateurs sur des collections triées.
Comme d'autres l'ont mentionné, il s'agit d'un algorithme externe, pas d'une méthode. Je suppose que c'est bien pour votre application.
Ce n'est pas un "opérateur" au sens du langage, mais il y a l'algorithme set_difference dans la bibliothèque standard:
http://www.cplusplus.com/reference/algorithm/set_difference.html
Bien entendu, les autres opérations de base sont également présentes (union, etc.), comme le suggère la section "Voir aussi" à la fin de l'article lié.
La réponse choisie est correcte, mais présente des erreurs de syntaxe.
Au lieu de
#include <algorithms>
utilisation
#include <algorithm>
Au lieu de
std::insert_iterator(result, result.end()));
utilisation
std::insert_iterator<set<int> >(result, result.end()));
Encore une fois, relancez à la rescousse:
#include <string>
#include <set>
#include <boost/range/algorithm/set_algorithm.hpp>
std::set<std::string> set0, set1, setDifference;
boost::set_difference(set0, set1, std::inserter(setDifference, setDifference.begin());
setDifference contiendra set0-set1.
Pas comme méthode, mais il y a la fonction d'algorithme externe set_difference
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result);
Apparemment c'est le cas.
C++ ne définit pas d'opérateur de différence entre ensembles mais vous pouvez définir le vôtre (en utilisant le code donné dans d'autres réponses):
template<class T>
set<T> operator -(set<T> reference, set<T> items_to_remove)
{
set<T> result;
std::set_difference(
reference.begin(), reference.end(),
items_to_remove.begin(), items_to_remove.end(),
std::inserter(result, result.end()));
return result;
}
Toutes les réponses que je vois ici sont O (n). Ne serait-ce pas mieux ?:
template <class Key, class Compare, class Allocator>
std::set<Key, Compare, Allocator>
set_subtract(std::set<Key, Compare, Allocator>&& lhs,
const std::set<Key, Compare, Allocator>& rhs) {
if (lhs.empty()) { return lhs; }
// First narrow down the overlapping range:
const auto rhsbeg = rhs.lower_bound(*lhs.begin());
const auto rhsend = rhs.upper_bound(*lhs.rbegin());
for (auto i = rhsbeg; i != rhsend; ++i) {
lhs.erase(*i);
}
return std::move(lhs);
}
Cela semble faire la bonne chose. Je ne suis pas sûr de savoir comment traiter le cas où le type de Compare
ne spécifie pas complètement son comportement, comme dans le cas où Compare
est un std::function<bool(int,int)>
, mais à part cela, cela semble fonctionner correctement et devrait ressembler à O ((chevauchement de chiffres) • log (lhs.size()
)).
Si lhs
ne contient pas *i
, il est probablement possible d'optimiser davantage en effectuant une recherche O (log (rhs.size()
)) pour le prochain élément de rhs
qui est> = le prochain élément de lhs
. Cela optimiserait le cas où lhs = {0, 1000}
et rhs = {1, 2, ..., 999}
effectueraient la soustraction dans le temps de log.