Имеется ли в структуре данных набора C++ STL оператор разности наборов?





Да, в заголовке алгоритмов есть функция set_difference.
Редактирует:
К вашему сведению, установленная структура данных может эффективно использовать этот алгоритм, как указано в его документация. Алгоритм также работает не только с наборами, но и с любой парой итераторов над отсортированными коллекциями.
Как уже упоминали другие, это внешний алгоритм, а не метод. По-видимому, это нормально для вашего приложения.
Не как метод, но есть функция внешнего алгоритма set_difference
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result);
Судя по всему, да.
Не «оператор» в языковом смысле, но в стандартной библиотеке есть алгоритм set_difference:
http://www.cplusplus.com/reference/algorithm/set_difference.html
Конечно, присутствуют и другие операции с базовыми наборами - (объединение и т. д.), Как это предлагается в разделе «См. Также» в конце связанной статьи.
Да, он есть в <algorithm> и называется: std::set_difference. Использование:
#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()));
В итоге набор result будет содержать s1-s2.
+1. К сожалению, когда мне это было нужно, я сдался и свернул свой собственный цикл :(
Кстати, если вы используете set_difference в неассоциативном классе контейнера, скажем, в векторе, сначала убедитесь, что элементы в обоих контейнерах отсортированы ...
#include <алгоритмы> -> Нет такого файла, должно быть <алгоритм>?
для set <string> мне пришлось квалифицировать std :: insert_iterator <set <string >> (...)
@stefanB: первый комментарий правильный, а второй: обычно используется std::inserter. Никакой квалификации не требуется, поскольку это функция.
Документы говорят, что set_difference требует сортировки обоих контейнеров. set реально отсортирован? Это не очевидно.
Выбран правильный ответ, но есть некоторые синтаксические ошибки.
Вместо
#include <algorithms>
использовать
#include <algorithm>
Вместо
std::insert_iterator(result, result.end()));
использовать
std::insert_iterator<set<int> >(result, result.end()));
или просто используйте std::inserter(result, result.end())
мы можем просто использовать
set_difference(set1.begin(), set1.end(), set2.begin(). set2,end(),std::back_inserter(result)).
std::back_inserter требует метода push_back() в целевом контейнере result. Это не сработает, если result - это std::set.
Пожалуйста, не задавайте вопросов в ответах.
Еще раз спешите на помощь:
#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 будет содержать set0-set1.
C++ не определяет оператор разницы наборов, но вы можете определить свой собственный (используя код, приведенный в других ответах):
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;
}
Все ответы, которые я вижу здесь, - O (n). Разве это не было бы лучше ?:
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);
}
Кажется, это правильно. Я не уверен, как поступить в случае, когда тип Compare не полностью определяет его поведение, например, если Compare является std::function<bool(int,int)>, но помимо этого, похоже, что это работает правильно и должно быть похоже на O ((num overlapping) • журнал (lhs.size())).
В случае, если lhs не содержит *i, вероятно, можно продолжить оптимизацию, выполнив поиск O (log (rhs.size())) для следующего элемента rhs, который> = следующий элемент lhs. Это позволит оптимизировать случай, когда lhs = {0, 1000} и rhs = {1, 2, ..., 999} будут выполнять вычитание за логарифмическое время.
Его можно использовать на паре отсортированных контейнеров Любые.