简体   繁体   中英

How to look for an element inside a set of sets in C++?

Following is my code:

set<set<int,greater<int>>> output;
set<int,greater<int>> k;

k.insert(5);
output.insert(k);

Now how do I find out if element 5 is present in my 'output' set or not?

And how do I find out which set, inside my 'output' set, the element 5 belongs to?

Use a simple for loop:

size_t ii = 0;
for (const auto& inner : output) {
    if (inner.count(5))
        std::cout << "found in set " << ii << std::endl;
    ++ii;
}

There's a pre C++20 and a C++20 (using ranges) solution

Pre-C++20 I'm using std::find_if and set::find . C++20 I'm using std::ranges::find_if and set::contains . For the C++20 I'm also using std::optional std::reference_wrapper return type. And concepts, so it's a generic solution applicable to all sets and maps.

#include <set>
#include <algorithm>

template<typename T, typename Comp = std::less<T>>
std::set<T, Comp> const* findInSetOfSets(std::set<std::set<T, Comp>> const& setOfSets, T const& value) {
    auto const it = std::find_if(cbegin(setOfSets), cend(setOfSets),
        [&](std::set<T, Comp> const& set) { return set.find(value) != end(set); } );
    if (it != cend(setOfSets)) return &*it;
    return nullptr;
}

#include <optional>
#include <functional>
#include <type_traits>

template<typename T, typename U>
concept hasContains = requires(T& t, U& u) {
    { t.contains(u) } -> std::same_as<bool>;
};

template<std::ranges::input_range R, typename T,
    typename U = std::remove_reference<R>::type::value_type>
    requires hasContains<U, T>
[[nodiscard]] auto findCpp20(R&& r, T const& value) noexcept
 ->std::optional<std::reference_wrapper<U const>> {
    auto it = std::ranges::find_if(r,
       [&](U const& u) { return u.contains(value); } );
    if (it != std::ranges::end(r)) return *it;
    return std::nullopt;
}

#include <cstdio>

int main(){
    std::set<std::set<int,std::greater<int>>> output;
    std::set<int,std::greater<int>> k;

    k.insert(5);
    output.insert(k);

    auto setPtr = findInSetOfSets(output, 5);
    if (setPtr != nullptr) printf("set found!\n");
    auto optionalSet = findCpp20(output, 5);
    if (optionalSet.has_value()) printf("set found!\n");
}

godbolt

Here's a boolean function that looks for element p inside a set of sets s

bool findelem(int p, set<set<int>> const& s) 
{
    for (auto itr1= s.cbegin(); itr1 != s.cend(); ++itr1) {
        for (auto itr2 = itr1->cbegin(); itr2 != itr1->cend(); ++itr2) {
            if (*itr2==p) {
                return true;
            }
        }
    }
    return false;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM