【发布时间】:2015-09-17 21:34:17
【问题描述】:
我有两个集合(std::set from <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)不管是否存在,使用自定义虚拟迭代器的方法是一个好的方法吗?
【问题讨论】:
-
仅仅识别常见元素的数量似乎过于复杂。为什么不直接使用循环?
-
很奇怪,当你从不真正使用交叉路口时,知道大小有什么意义?你考虑清楚了吗? Read this.
-
与自定义迭代器相比,创建一个具有
insert()成员的自定义“容器”会更简单,并与insert_iterator一起使用。 -
@HansPassant 为什么你觉得这很奇怪?我能想到很多情况。本质上它是重叠的区域。
-
@JonathanWakely 谢谢,我会考虑的