简体   繁体   English

快速查找不在向量C ++中的所有元素

[英]Quickly find all elements not in a vector c++

I have a vector of points allPoints and a vector of points badPoints . 我有点allPoints的向量和点badPoints的向量。 I want to quickly get a set of goodPoints where it is everything in allPoints that is not in badPoints. 我要赶紧弄一套goodPoints它是一切allPoints不在badPoints。 Currently I have: 目前我有:

    int i = 0;
    for (auto point : allPoints)
    {
        bool add = true;
        for (auto x : badPoints)
        {
            if (point == x)
            {
                add = false;
                break;
            }
        }
        if (add)
        {
            goodPoints.insert(point);
        }
        i++;
    }

I feel like this is slower than it should be but I don't know a better way to do it. 我觉得这比应该的要慢,但是我不知道有什么更好的方法。 Any ideas? 有任何想法吗?

Depending on the dimensions of the points, sorting might not be very viable (you can sort only in one dimension, for example). 根据点的尺寸,排序可能不太可行(例如,只能在一维中排序)。 A better way would be to have a kD tree (eg, if the points are in 2D, make a 2D-tree structure for the points), this way, instead of comparing all the points, you just need to compare with the points in the leaves of the tree. 更好的方法是使用kD树(例如,如果点为2D,则为这些点创建2D树结构),这样,无需比较所有点,只需与树上的叶子。

Another, simpler but not as elegant, way is to divide your space into a grid. 另一种更简单但不那么优雅的方法是将您的空间分成网格。 For example, if the points are in 2D, divide your plane into a NxN grid, and depending on which grid cell your cells fall in, check for overlap only inside that cell. 例如,如果点为2D,则将平面划分为NxN网格,然后根据单元格所在的网格单元格,检查仅在该单元格内是否重叠。 You need to play with the size of the cells (or N) to find a balance between the number of cells and number of points inside the cells. 您需要计算像元(或N)的大小,才能找到像元数与像元内部点数之间的平衡。

In case your data are not sorted, as suggested in the comments, use std::set_difference , like this: 如果未按照注释中的建议对数据进行排序,请使用std :: set_difference ,如下所示:

#include <iostream>     // std::cout
#include <algorithm>    // std::set_difference, std::sort
#include <vector>       // std::vector

int main () {
  std::vector<int> allPoints = {5,10,15,20,25};
  std::vector<int> badPoints = {50,40,30,20,10};
  std::vector<int> v(10);                      // 0  0  0  0  0  0  0  0  0  0

  std::sort(allPoints.begin(), allPoints.end());     //  5 10 15 20 25
  std::sort(badPoints.begin(), badPoints.end());   // 10 20 30 40 50

  std::vector<int>::iterator it = std::set_difference(
        allPoints.begin(), allPoints.end(), badPoints.begin(), badPoints.end(), v.begin());
                                                //  5 15 25  0  0  0  0  0  0  0
  v.resize(it - v.begin());                     //  5 15 25

  std::cout << "Good points are " << (v.size()) << " in number:\n";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

Output: 输出:

Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall -std=c++0x main.cpp 
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out 
Good points are 3 in number:
 5 15 25

Complexity 复杂

Up to linear in 2*(count1+count2)-1 (where countX is the distance between firstX and lastX): Compares and assigns elements. 线性最大为2 *(count1 + count2)-1(其中countX是firstX和lastX之间的距离):比较并分配元素。

One approach you can do is to utilize use of another data structure called set unique; 您可以采取的一种方法是利用另一种称为集唯一的数据结构;

Like instead of int, your point structure will come. 就像代替int一样,您的点结构将会出现。 For simplicity, I am making use of int. 为了简单起见,我使用int。

So you implementation will look something like this 所以您的实现将如下所示

set<int> unique;
int i = 0;
for (auto point : badPoints)
{
    unique.insert(point);
}
for(auto point : allPoints)
{
    // it is not present in unique that means it's not a bad point
    if(unique.find(point) == unique.end())
    {
       goodPoints.insert(point);
    }
 }

Hope this helps ! 希望这可以帮助 !

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM