Как сравнить два 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

Пока ключи одинаковы и размер одинаков, контейнеры будут сравниваться одинаково независимо от того, в каком порядке находятся ключи.

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