我被给予两个集合(来自
一种直接的方法是:
<set>
的std::set),我想知道它们的交集大小。我可以使用<algorithm>
中的std::set_intersection,但我必须提供一个输出迭代器来将交集复制到其他容器中。一种直接的方法是:
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()));
接下来使用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);
}
};
使用这个工具,我们可以做到
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);
之后计数器将持有交集的大小。
这段代码要多得多。我的问题是:
1)是否有一种标准(库)方法或标准技巧可在不存储整个交集的情况下获取交集的大小? 2)无论是否存在,使用自定义虚拟迭代器的方法是否可行?
insert()
成员的自定义“容器”,并使用该容器与insert_iterator
更为简单。 - Jonathan Wakely