C++ 使用stl对两个集合并集中的元素进行计数

C++ 使用stl对两个集合并集中的元素进行计数,c++,stl,set,C++,Stl,Set,我有两个集合,我想知道一个集合中至少有多少个元素。这是中的一个函数set\u union,它将union写入另一个集合,但我只需要数字。我能在不保存元素的情况下使用stl找到它吗?我不知道有这样的算法。也就是说,你可以用set\u union的勇气编写自己的代码来实现这一点;像这样: #include <iostream> #include <set> // Counts the number of elements that would be in the union

我有两个集合,我想知道一个集合中至少有多少个元素。这是
中的一个函数
set\u union
,它将union写入另一个集合,但我只需要数字。我能在不保存元素的情况下使用stl找到它吗?

我不知道有这样的算法。也就是说,你可以用
set\u union
的勇气编写自己的代码来实现这一点;像这样:

#include <iostream>
#include <set>

// Counts the number of elements that would be in the union
template <class Compare, class InputIterator1, class InputIterator2>
size_t set_union_size(InputIterator1 first1, InputIterator1 last1,
                      InputIterator2 first2, InputIterator2 last2,
                      Compare comp)
{
    size_t __result = 0;
    for (; first1 != last1;)
    {
        if (first2 == last2)
            return __result + std::distance(first1, last1);
        if (comp(*first2, *first1))
        {
            ++__result;
            ++first2;
        }
        else
        {
            ++__result;
            if (!comp(*first1, *first2))
                ++first2;
            ++first1;
        }
    }
    return __result + std::distance(first2, last2);
}

int main () {
    std::set<int> s1 = { 0, 1, 2, 3, 4 };
    std::set<int> s2 = { 0, 2, 4, 6, 8 };
    std::cout
        << set_union_size(s1.begin(), s1.end(), s2.begin(), s2.end(), std::less<int>())
        << std::endl;
    }
#包括
#包括
//计算将在联合中的元素数
模板
大小\u t集合\u并集\u大小(输入计数器1 first1,输入计数器1 last1,
输入计数器2优先2,输入计数器2最后2,
比较(比较)
{
尺寸t结果=0;
对于(;first1!=last1;)
{
if(first2==last2)
返回结果+标准::距离(first1,last1);
如果(公司(*first2,*first1))
{
++__结果;
++前2名;
}
其他的
{
++__结果;
如果(!comp(*first1,*first2))
++前2名;
++第一个1;
}
}
返回结果+标准::距离(first2,last2);
}
int main(){
std::set s1={0,1,2,3,4};
std::set s2={0,2,4,6,8};
标准::cout

我同意Marshall Clow的观点;我不相信有现成的算法可以做到这一点。这是我一直在玩弄的一个想法。它是一个简单的类,提供一个push_-back方法,只增加一个计数器。你可以将它与std::back_插入器一起用作输出迭代器

#include <initializer_list>
#include <iterator>
#include <iostream>
#include <algorithm>

template <typename T>
class CountingPushBack
{
  public:
  using value_type = T;

  void push_back(T const &) {++count;}

  std::size_t get_count() const {return count;}

  private:
  std::size_t count = 0;
};

int main()
{
  std::initializer_list<int> il1 = { 0, 1, 2, 3, 4 };
  std::initializer_list<int> il2 = { 0, 2, 4, 6, 8 };

  CountingPushBack<int> cp;

  std::set_union(il1.begin(), il1.end(), 
                 il2.begin(), il2.end(), 
                 std::back_inserter(cp));

  std::cout << cp.get_count() << std::endl;
}
#包括
#包括
#包括
#包括
模板
类计数推回
{
公众:
使用值_type=T;
void push_back(T const&){++count;}
std::size\u t get\u count()常量{return count;}
私人:
标准::大小\u t计数=0;
};
int main()
{
std::初始值设定项\列表il1={0,1,2,3,4};
std::初始值设定项_list il2={0,2,4,6,8};
倒推计数;
std::set_union(il1.begin(),il1.end(),
il2.begin(),il2.end(),
标准:背部插入器(cp);

虽然SCFrench的解决方案很好,但它确实需要一个容器,而我们只需要一个
back\u insert\u迭代器

#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>

template <typename T>
class count_back_inserter {
    size_t &count;
public:
    typedef void value_type;
    typedef void difference_type;
    typedef void pointer;
    typedef void reference;
    typedef std::output_iterator_tag iterator_category;
    count_back_inserter(size_t &count) : count(count) {};
    void operator=(const T &){ ++count; }
    count_back_inserter &operator *(){ return *this; }
    count_back_inserter &operator++(){ return *this; }
};

我不知道你不计算工会的原因是什么(可能太贵了吧?)∪ B) +尺寸(A)∩ B) =尺寸A+尺寸B。如果可以计算交叉口的尺寸。
int main(){
    std::vector<int> v1 = {1, 2, 3, 4, 5}; 
    std::vector<int> v2 = {      3, 4, 5, 6, 7}; 
    size_t count = 0;
    set_union(v1.begin(), v1.end(),
              v2.begin(), v2.end(),
              count_back_inserter<int>(count));
    std::cout << "The number of elements in the union is " << count << std::endl;
}