Разница в наборах C++ STL

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
70
0
53 274
10

Ответы 10

Да, в заголовке алгоритмов есть функция set_difference.

Редактирует:

К вашему сведению, установленная структура данных может эффективно использовать этот алгоритм, как указано в его документация. Алгоритм также работает не только с наборами, но и с любой парой итераторов над отсортированными коллекциями.

Как уже упоминали другие, это внешний алгоритм, а не метод. По-видимому, это нормально для вашего приложения.

Его можно использовать на паре отсортированных контейнеров Любые.

xtofl 12.11.2008 17:16

Не как метод, но есть функция внешнего алгоритма set_difference

template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
                              InputIterator2 first2, InputIterator2 last2,
                              OutputIterator result);

http://www.sgi.com/tech/stl/set_difference.html

Судя по всему, да.

SGI - set_difference

Не «оператор» в языковом смысле, но в стандартной библиотеке есть алгоритм 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. К сожалению, когда мне это было нужно, я сдался и свернул свой собственный цикл :(

peterchen 12.11.2008 17:52

Кстати, если вы используете set_difference в неассоциативном классе контейнера, скажем, в векторе, сначала убедитесь, что элементы в обоих контейнерах отсортированы ...

paxos1977 13.11.2008 04:06

#include <алгоритмы> -> Нет такого файла, должно быть <алгоритм>?

stefanB 07.08.2009 06:12

для set <string> мне пришлось квалифицировать std :: insert_iterator <set <string >> (...)

stefanB 07.08.2009 06:16

@stefanB: первый комментарий правильный, а второй: обычно используется std::inserter. Никакой квалификации не требуется, поскольку это функция.

rlbond 26.12.2009 22:29

Документы говорят, что set_difference требует сортировки обоих контейнеров. set реально отсортирован? Это не очевидно.

Ayrat 06.09.2020 21:43

Выбран правильный ответ, но есть некоторые синтаксические ошибки.

Вместо

#include <algorithms>

использовать

#include <algorithm>

Вместо

std::insert_iterator(result, result.end()));

использовать

std::insert_iterator<set<int> >(result, result.end()));

или просто используйте std::inserter(result, result.end())

rlbond 26.12.2009 22:29

мы можем просто использовать

 set_difference(set1.begin(), set1.end(), set2.begin(). set2,end(),std::back_inserter(result)).
std::back_inserter требует метода push_back() в целевом контейнере result. Это не сработает, если result - это std::set.
Attila 18.01.2013 14:16

Пожалуйста, не задавайте вопросов в ответах.

user650261 24.10.2018 07:01

Еще раз спешите на помощь:

#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} будут выполнять вычитание за логарифмическое время.

Другие вопросы по теме