我尝试使用std::set
以便在容器中包含唯一元素。
因为我有3D对象:
Class Object3D{
private:
float x;
float y;
float z;
}
(A.x==B.x && A.y==B.y && A.z==B.z)
时,这些对象是相同的
在std :: set实现中有一个元素A==B if (!(A < B) && !(B>A))
我的比较是不可能的......我试图重载==
运算符
当我调用insert(a)
时,我选择了set container来比较值。
我用std::vector v
和他的迭代器做了类似的事情:
if(!(A).inVector()){
v.push_back(A);
}
使用
bool inVector(){
for(itr = v.begin();itr != v.end();itr++){
if(this->x==(*itr)->x && this->y==(*itr)->y && this->z==(*itr)->z){
return true;
}
}
return false;
}
检查每个对象(10000-100000)的复杂性是很昂贵的 有人有想法吗?
答案 0 :(得分:7)
您需要为您的班级实施严格的弱排序<
。最简单的方法是使用tuple
提供的词典排序:
#include <tuple>
class Object3D
{
public:
bool operator<(Object3D const & rhs) const
{
return std::tie(x, y, z) < std::tie(rhs.x, rhs.y, rhs.z);
}
// ...
};
答案 1 :(得分:4)
@OP:std::set
是一个唯一的,有序的容器。它需要显式传递operator<
或比较器,这实现了严格的弱排序。
如果您不希望对您的元素强加订购,不使用订购的容器。如果您只想检测唯一性而不强制订购,则可以使用std::unordered_set
。
答案 2 :(得分:2)
你需要提供一个比较器。您不想实施operator<
,我同意该决定。您不应该为了满足某些容器的约束而为您的类提供无意义的函数。谢天谢地,您不需要operator<
。但是你确实需要一个行为类似于operator<
的函数。它不必意味着一个对象被认为小于另一个对象。它只需要提供严格弱的排序。你可以给它任何你想要的名字。例如:
bool Compare_by_x_then_y_then_z(const Object3D& lhs, const Object3D& rhs)
{
if (lhs.getX() != rhs.getX()) return lhs.getX() < rhs.getX();
if (lhs.getY() != rhs.getY()) return lhs.getY() < rhs.getY();
return lhs.getZ() < rhs.getZ();
}
然后,您将此函数提供给集合的构造函数:
typedef bool(*compT)(const Object3D&, const Object3D&);
std::set<Object3D,compT> objects(Compare_by_x_then_y_then_z);
答案 3 :(得分:1)
你有提供比较运算符,因为std::set
需要它来实现它。
一个简单的小于运算符看起来像这样:
bool Object3D::operator<(const Object3D& other) const {
if(x != other.x) return x < other.x;
if(y != other.y) return y < other.y;
return z < other.z;
}
答案 4 :(得分:1)
您必须声明运营商&lt;。你可以这样做
bool operator<(const Object3D& a, const Object3D& b)
{
if (a.x < b.x) return true;
if (b.x < a.x) return false;
if (a.y < b.y) return true;
if (b.y < a.y) return false;
if (a.z < b.z) return true;
if (b.z < a.z) return false;
return false;
}
这是任意的,但并不重要。只要运营商&lt;给出一致的顺序,你就可以了。