I do not know your requirements exactly, but if the order of the element in vec_pair not important, I suppose you can replace it with std::multimap or, I suppose, better, std::unordered_multimap .
I mean (using example A , equal to int as an example), instead
using A = int; std::vector<std::pair<A, A>> const vec_pair { {1, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {4, 1}, {4, 2}, {4, 3}, {4, 4} };
you can use
std::unordered_multimap<A, A> const cM { {1, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {4, 1}, {4, 2}, {4, 3}, {4, 4} };
If you want vec_pair be a vector of pairs, using the fact that vec_pair is a constant (I understand correctly?), You can create a constant unordered multimar.
The advantage of this solution is that if you find that the card key is not in vec , you can avoid the test for all values ββwith the same key.
Additionally: if you build a set (or, better, unordered_set ) starting with vec (this is not enough, if I understand correctly, you can check the pairs as follows
for ( auto ci = cM.cbegin() ; ci != cM.cend() ; ) { auto val = ci->first; auto cnt = cM.count(val); if ( s.end() == s.find(val) ) { for ( auto i = 0U ; i < cnt ; ++i ) ++ci; } else for ( auto i = 0U ; i < cnt ; ++i, ++ci ) if ( s.end() != s.find(ci->second) ) std::cout << "- good for <" << val << ", " << ci->second << '>' << std::endl; }
I know: this is not an elegant solution.
Another way is to use a combination of map and set (unorderd, better) and instead
std::vector<std::pair<A, A>> const vec_pair { {1, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {4, 1}, {4, 2}, {4, 3}, {4, 4} };
use (or construct)
std::unordered_map<A, std::unordered_set<A>> const cM { {1, {1, 2, 3, 4}}, {2, {1, 2, 3, 4}}, {3, {1, 2, 3, 4}}, {4, {1, 2, 3, 4}} };
In this case, the search part is more elegant (IMHO)
for ( auto const & p : cM2 ) if ( s.end() != s.find(p.first) ) for ( auto const & sec : p.second ) if ( s.end() != s.find(sec) ) std::cout << "- good for <" << p.first << ", " << sec << '>' << std::endl;
Below is a complete compiled example for both solutions
#include <vector> #include <utility> #include <iostream> #include <unordered_map> #include <unordered_set> int main() { using A = int; std::unordered_multimap<A, A> const cM { {1, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {4, 1}, {4, 2}, {4, 3}, {4, 4} }; std::unordered_set<A> s { 4, 3 }; for ( auto ci = cM.cbegin() ; ci != cM.cend() ; ) { auto val = ci->first; auto cnt = cM.count(val); if ( s.end() == s.find(val) ) { for ( auto i = 0U ; i < cnt ; ++i ) ++ci; } else for ( auto i = 0U ; i < cnt ; ++i, ++ci ) if ( s.end() != s.find(ci->second) ) std::cout << "- good for <" << val << ", " << ci->second << '>' << std::endl; } std::unordered_map<A, std::unordered_set<A>> const cM2 { {1, {1, 2, 3, 4}}, {2, {1, 2, 3, 4}}, {3, {1, 2, 3, 4}}, {4, {1, 2, 3, 4}} }; for ( auto const & p : cM2 ) if ( s.end() != s.find(p.first) ) for ( auto const & sec : p.second ) if ( s.end() != s.find(sec) ) std::cout << "- good for <" << p.first << ", " << sec << '>' << std::endl; }