在指针向量中添加非重复值的最有效方法

时间:2014-07-28 06:44:02

标签: c++ vector unique

我有这样的矢量

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() );

然而,两种代码的结果都不同。排序/擦除是否适用于指针向量?

有任何解决这个问题的建议吗?

3 个答案:

答案 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但是你的速度差异将根据缓存效果和架构而有所不同,所以请将这个测量结果与盐分进行对比。