我有这样的矢量
vector<Point*> points;
我想为此向量添加一个新点。然而,我有最多50个内部矢量点,但其中许多是重复。实现添加非重复值的最有效方法是什么。直到现在我这样做了:
boolean add_point(vector<Point*> *p, int x, int y){
for(vector<Point*>::iterator i = p->begin(); i != p->end(); i++){
if((*i)->x == x && (*i)->y == y)
return false;
}
p->push_back(new Point(x,y));
return true;
}
然而,当我调用该函数时,我的app的执行时间增加了很多。
根据我试图做的堆栈主题之一:
sort( points.begin(), points.end() );
points.erase( unique( points.begin(), points.end() ), points.end() );
然而,两种代码的结果都不同。排序/擦除是否适用于指针向量?
有任何解决这个问题的建议吗?
答案 0 :(得分:3)
假设您的Point
结构类似于
struct Point { int x, y; }
然后只将Points
自己存储在向量中,并提供比较函数
bool operator==(Point const& p1, Point const& p2)
{
return p1.x == p2.x && p1.y == p2.y
}
bool operator<(Point const& p1, Point const& p2)
{
return p1.x != p2.x ? p1.x < p2.x : p1.y < p2.y;
}
之后,您可以使用以下内容删除重复项:
std::sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
如果您希望容器自动防止重复,请使用std::set<Point>
/ std::unordered_set<Point>
(您需要为后者提供std::hash
的专业化),尽管使用带有向量的向量最终排序和删除重复项可能会更快。正如@PorkyBrain指出的那样,您可以在插入时使用std::lower_bound
对矢量进行排序,并避免最终排序。
所有这些中最有效的完全取决于您的使用案例,因为总是首先使用最简单的方法编写程序,然后分析是否需要改进。
答案 1 :(得分:0)
使用std::unordered_map
。
这些点将被散列,因此在检查大量重复项时,存储应该更快。
答案 2 :(得分:0)
将点直接放入矢量可能更快。在处理POD类型时保持已排序的向量(通过使用lower_bounds添加)通常是最快的,因为它是最缓存友好的。这是一个例子:
void addToSortedVector(std::vector<Point>& v, Point p){
auto it = std::lower_bound(v.begin(),v.end(),p);
if(it == v.end() || !(*it == p)){
v.emplace(it,std::move(p));
}
}
你可以在这里看到约1.5倍的速度差异:http://ideone.com/E2gqOd但是你的速度差异将根据缓存效果和架构而有所不同,所以请将这个测量结果与盐分进行对比。