Как сравнить два std::set?
Я делаю такое сравнение двух std::set
#include <cstdlib>
#include <cstdio>
using namespace std;
#include <vector>
#include <set>
int main(int argc, char** argv)
{
int myints1[]= {10,20,30,40,50};
int myints2[]= {50,40,30,20,10};
std::set<int> s1 (myints1,myints1+5);
std::set<int> s2(myints2,myints2+5);
if(s1==s2){
printf("sets: true");
}else printf("sets: false");
std::set<int>::iterator it2=s2.begin();
for(std::set<int>::iterator it1=s1.begin();it1!=s1.end();it1++){
printf("\ns1: %d s2: %d",*it1,*it2);
it2++;
}
}
выход:
sets: true
s1: 10 s2: 10
s1: 20 s2: 20
s1: 30 s2: 30
s1: 40 s2: 40
s1: 50 s2: 50
Вопрос:
Это правильный способ сделать это? Или есть какой-то другой (особый) способ сравнения двух множеств?
5 ответов
Да, operator==
правильно определен для всех стандартных контейнеров (кроме неупорядоченных контейнеров - на основе 23.2.5.2 стандарта) и обычно выполняет лексикографическое сравнение. Смотрите, например, здесь. Соответствующая цитата:
Проверяет, равны ли значения lhs и rhs, т. Е. Имеет ли lhs.size() == rhs.size() и имеет ли каждый элемент в lhs эквивалентный элемент в rhs в той же позиции.
поскольку std::set
является упорядоченным контейнером, любой набор с одинаковыми размерами и одинаковыми элементами (учитывая, что компараторы одинаковы) обязательно будет иметь их в одном и том же положении, следовательно, будет сравниваться.
В заголовке стандартной библиотеки C++ есть несколько операций над множествами <algorithm>
,
std::set_difference
дает те элементы, которые находятся в наборе 1, но не в наборе 2.
std::set_intersection
дает те элементы, которые находятся в обоих наборах.
std::set_symmetric_difference
дает те элементы, которые появляются в одном из наборов, но не в обоих.
std::set_union
дает те элементы, которые находятся в наборе 1 или 2.
Приведенные выше алгоритмы могут также применяться к контейнерам STL, отличным от std::set
, но контейнеры должны быть отсортированы в первую очередь (std::set
сортируется по умолчанию).
Другим способом было бы это:
template<typename Set>
bool set_compare(Set const &lhs, Set const &rhs){
return lhs.size() == rhs.size()
&& equal(lhs.begin(), lhs.end(), rhs.begin());
}
Вдохновлен элегантным ответом здесь.
Стандарт C++11 на ==
за std::set
Другие отметили, чтоoperator==
сравнивает std::set
содержание и работает, но вот цитата из стандартного черновика C++11 N3337, которая, как мне кажется, подразумевает это.
Цитата точно такая же, как и для std::vector
который я подробно интерпретировал по адресу: C++: Сравнение двух векторов
Вкратце, чтобы избежать дублирования с другим ответом:
- 23.2.1 "Общие требования к контейнерам" гласят, что все контейнеры используют
equal()
заoperator==
- 25.2.11 "Равный" определяет
equal
и явно показывает, что он перебирает оба контейнера, сравнивая элементы каждого
В С++11 и выше вы можете использовать для сравнения, равны ли 2 набора или нет.
std::set<int> contOne{ 10,20,30,40,50 };
std::set<int> contTwo{ 50,40,30,20,10 };
std::cout << (contOne == contTwo) ? 1 : 0; // 1
Кроме того, вы можете использовать==
чтобы сравнить 2 неупорядоченных набора .
std::unordered_set<int> contOne{ 10,20,30,40,50 };
std::unordered_set<int> contTwo{ 50,40,30,20,10 };
std::cout << (contOne == contTwo) ? 1 : 0; // 1
Пока ключи одинаковы и размер одинаков, контейнеры будут сравниваться одинаково независимо от того, в каком порядке находятся ключи.