how to compare two std::set?

2020-05-29 16:06发布

问题:

I do such comparison of two 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++;
    }
}

output:

sets: true
s1: 10  s2: 10
s1: 20  s2: 20
s1: 30  s2: 30
s1: 40  s2: 40
s1: 50  s2: 50

Question:

Is this the right way to do it? Or is any other (special) way of comparing two sets?

回答1:

Yes, operator== is correctly defined for all standard containers (except the unordered containers - based on 23.2.5.2 of the standard), and will generally do a lexicographic comparison. See for example here. The relevant quote:

Checks if the contents of lhs and rhs are equal, that is, whether lhs.size() == rhs.size() and each element in lhs has equivalent element in rhs at the same position.

Since std::set is an ordered container, any set with the same size and same elements (given the comparators are the same) will necessarily have them in the same position, hence will compare equal.



回答2:

There are several set operations in C++ standard library header <algorithm>.

std::set_difference gives those elements that are in set 1 but not set 2.

std::set_intersection gives those elements that are in both sets.

std::set_symmetric_difference gives those elements that appear in one of the sets but not both.

std::set_union gives those elements that are in either set 1 or set 2.

The algorithms above can also be applied to STL containers other than std::set, but the containers have to be sorted first (std::set is sorted by default).



回答3:

Another way would be this:

template<typename Set>

bool set_compare(Set const &lhs, Set const &rhs){
    return lhs.size() == rhs.size() 
        && equal(lhs.begin(), lhs.end(), rhs.begin());
}

Inspired from the elegant answer here.



回答4:

C++11 standard on == for std::set

Others have mentioned that operator== does compare std::set contents and works, but here is a quote from the C++11 N3337 standard draft which I believe implies that.

The quote is exactly the same as that for std::vector which I have interpreted in full detail at: C++: Comparing two vectors

As a short summary to avoid duplication with that other answer:

  • 23.2.1 "General container requirements" states that all containers use equal() for operator==
  • 25.2.11 "Equal" defines equal and explicitly shows that it iterates over both containers comparing the elements of each


标签: c++ set std