Поскольку std::set
является отсортированным контейнером, вы можете сравнить установленные границы, чтобы увидеть, могут ли они пересекаться, и, если да, выполнить дорогостоящую операцию STL.
Edit:
Вот где серьезная рыбалка на моллюсков ...
Весь код, опубликованный до сих пор, пытается повторно реализовать то, что уже есть в . Вот суть set_intersection
:
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator>
_OutputIterator
set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
_OutputIterator __result)
{
while (__first1 != __last1 && __first2 != __last2)
if (*__first1 < *__first2)
++__first1;
else if (*__first2 < *__first1)
++__first2;
else
{
*__result = *__first1;
++__first1;
++__first2;
++__result;
}
return __result;
}
Довольно оптимально уже, за исключением присваивания выходному итератору, который не нужен для нахождения только факта, являются ли два набора объединенными. Это может быть использовано для изменения флага следующим образом:
/// fake insert container
template <typename T> struct intersect_flag
{
typedef int iterator;
typedef typename T::const_reference const_reference;
bool flag_; // tells whether given sets intersect
intersect_flag() : flag_( false ) {}
iterator insert( iterator, const_reference )
{
flag_ = true; return 0;
}
};
// ...
typedef std::set<std::string> my_set;
my_set s0, s1;
intersect_flag<my_set> intf;
// ...
std::set_intersection( s0.begin(), s0.end(),
s1.begin(), s1.end(), std::inserter( intf, 0 ));
if ( intf.flag_ ) // sets intersect
{
// ...
Это позволяет избежать копирования объектов из исходных наборов и позволяет повторно использовать алгоритмы STL.