set_interaction自定义矢量不起作用的示例

set_interaction example with custom vector not working

本文关键字:不起作用 interaction 自定义 set      更新时间:2023-10-16

我希望- v and w -两个自定义向量的交集,然后从原始向量- v中删除公共元素。但不知何故,在我的情况下,y的大小总是0

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class A{
public:
int x;
A(int i) { x = i; } 
~A() {}
void getx() { cout << x << " "; } 
friend ostream &operator<<(ostream &o, const A&a) {
cout << a.x;
return o;
}
};
struct mycomparer {
bool operator()(const A* a, const A* b) {
return a->x < b->x;
}
};
int main()
{
vector<A*> v;
v.push_back(new A(1));
v.push_back(new A(2));
v.push_back(new A(4));
v.push_back(new A(3));
v.push_back(new A(5));
vector<A*> w;
w.push_back(new A(3));
w.push_back(new A(2));
vector<A*> y;
vector<A*>::iterator it, st;
it = set_intersection(v.begin(), v.end(), w.begin(), w.end(), y.begin(), mycomparer());
cout << " y size "  << y.size() << endl;
if (y.size()) {
for (st = y.begin(); st != y.end(); st++)
v.erase(st);
}
for (st = v.begin(); st != v.end(); st++) {
printf("%d ", (*st)->x);
}
cout << endl;
return 0;
}

这只是我写的一个样本,我的意图不是检查任何其他C++规则。

你没有遵守std::set_intersection的要求。

构造从d_first开始的排序区域,该区域由在排序区域[first1, last1)[first2, last2)中找到的元素组成。如果找到某个元素在[first1, last1)中 m 次,在[first2, last2)中找到 n 次,则前std::min(m, n)个元素将从第一个范围复制到目标范围。保留等效元素的顺序。生成的范围不能与任一输入范围重叠。

vw都没有排序 w.r.tmycomparer.这是第一个未定义的行为。

仅仅传递y.begin()并不意味着元素被添加到y,为此您需要std::back_inserter(y)。这是第二个未定义的行为。

你没有遵守std::vector::erase的要求。它的参数是vector的迭代器。您使用的是来自y的迭代器,而不是v。这是第三种未定义的行为。

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
class A{
public:
int x;
A(int i) { x = i; } 
~A() {}
void getx() { cout << x << " "; } 
friend ostream &operator<<(ostream &o, const A&a) {
cout << a.x;
return o;
}
};
struct mycomparer {
bool operator()(const A* a, const A* b) {
return a->x < b->x;
}
};
int main()
{
std::vector<A*> v;
v.push_back(new A(1));
v.push_back(new A(2));
v.push_back(new A(4));
v.push_back(new A(3));
v.push_back(new A(5));
std::sort(v.begin(), v.end(), mycomparer());
std::vector<A*> w;
w.push_back(new A(3));
w.push_back(new A(2));
std::sort(w.begin(), w.end(), mycomparer());
std::vector<A*> y;
set_intersection(v.begin(), v.end(), w.begin(), w.end(), std::back_inserter(y), mycomparer());
std::cout << " y size "  << y.size() << std::endl;
for (st = y.begin(); st != y.end(); st++)
v.erase(std::find(v.begin(), v.end(), *st));
for (st = v.begin(); st != v.end(); st++) {
std::cout << (*st)->x) << std::endl;
}
return 0;
}

顺便说一句,您可以使用std::set_difference来查找v中的元素,而不是直接在w中查找元素。

你的代码有很多问题...我只是把它们放在修改后的代码中

#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
// don't using namespace std;
class A {
private:
int x; // don't expose internals
public:
constexpr A(int i) noexcept : x(i) {}
constexpr int GetX() const noexcept { return x; } // don't make a getter to print
friend std::ostream& operator<< (std::ostream& o, const A& a) {
o << a.x; // don't push to cout in an ostream operator <<
return o;
}
};
// use lambda instead of functors
static constexpr auto mycomparer =
[](std::shared_ptr<A> const& a, std::shared_ptr<A> const& b) noexcept {
return a->GetX() < b->GetX();
};
int main()
{
// you were not deleting the new elements: memory leak
std::vector<std::shared_ptr<A>> v; // e.g. use smart pointers
v.push_back(std::make_shared<A>(1));
v.push_back(std::make_shared<A>(2));
v.push_back(std::make_shared<A>(4));
v.push_back(std::make_shared<A>(3));
v.push_back(std::make_shared<A>(5));
std::vector<std::shared_ptr<A>> w;
w.push_back(std::make_shared<A>(3));
w.push_back(std::make_shared<A>(2));
std::vector<std::shared_ptr<A>> y;
//you have to sort before calling set_intersection
std::sort(std::begin(v), std::end(v), mycomparer);
std::sort(std::begin(w), std::end(w), mycomparer);
std::set_intersection(
std::cbegin(v), std::cend(v), // use const iterators
std::cbegin(w), std::cend(w),
std::back_inserter(y), mycomparer); // you cannot iterate over an empty array. Use the backinserter
std::cout << " y size " << y.size() << 'n';
// you cannot use an iterator to a vector y to delete from vector v!
//if (y.size() > 0) { // not required
for (auto const& el : y)
v.erase(std::find(std::cbegin(v), std::cend(v), el)); 
//}
for (auto const& el : v) {
std::cout << el->GetX() << " ";
}
std::cout << 'n'; // prefer n over endl for speed
//return 0; // not required
}

1(在向量w中,您应该先推送new A(2),然后再推送new A(3)。对于您的实际代码,您的向量必须事先根据比较器进行排序,如前所述,如前所述,否则您绝对无法使用set_intersection。

2( 向量y的大小为 0,因为set_intersection不会在迭代器中插入新元素,而是使用运算符=赋值。而不是y.begin()你应该使用std::back_inserter(y),它实际上会在赋值时插入元素。