我有两组(std :: set from <set>),我想知道它的大小.我可以使用std :: set_intersection <algorithm>,但我必须提供一个输出迭代器来将交集复制到其他容器中.
一种直截了当的方式
set<int> s1{1,2,3,4,5};
set<int> s2{4,5,6,7,8,9,0,1};
vector<int> v;
set_intersection(
s1.begin(), s1.end(), s2.begin(), s2.end(),
inserter(v, v.begin()));
Run Code Online (Sandbox Code Playgroud)
之后v.size()给出了交集的大小.但是,即使我们不对它进行任何操作,也必须存储交集.
为了避免这种情况,我试图实现一个虚拟输出迭代器类,它只计算,但它不分配:
template<typename T>
class CountingOutputIterator {
private:
int* counter_;
T dummy_;
public:
explicit CountingOutputIterator(int* counter) :counter_(counter) {}
T& operator*() {return dummy_;}
CountingOutputIterator& operator++() { // ++t
(*counter_)++;
return *this;
}
CountingOutputIterator operator++(int) { // t++
CountingOutputIterator ret(*this);
(*counter_)++;
return ret;
}
bool operator==(const CountingOutputIterator& c) {
return counter_ == c.counter_; // same pointer
}
bool operator!=(const CountingOutputIterator& c) {
return !operator==(c);
}
};
Run Code Online (Sandbox Code Playgroud)
使用我们可以做的
set<int> s1{1,2,3,4,5};
set<int> s2{4,5,6,7,8,9,0,1};
int counter = 0;
CountingOutputIterator<int> counter_it(&counter);
set_intersection(
s1.begin(), s1.end(), s2.begin(), s2.end(), counter_it);
Run Code Online (Sandbox Code Playgroud)
之后计数器保持交叉点的大小.
然而,这是更多的代码.我的问题是:
1)是否有标准(库)方法或标准技巧来获得交叉点的大小而不存储整个交叉点?2)无论是否有,自定义虚拟迭代器的方法是否合适?
Jon*_*ely 17
编写一个遍历两个集合寻找匹配元素的循环并不难,或者你可以这样做,这比自定义迭代器简单得多:
struct Counter
{
struct value_type { template<typename T> value_type(const T&) { } };
void push_back(const value_type&) { ++count; }
size_t count = 0;
};
template<typename T1, typename T2>
size_t intersection_size(const T1& s1, const T2& s2)
{
Counter c;
set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), std::back_inserter(c));
return c.count;
}
Run Code Online (Sandbox Code Playgroud)