我有一个点allPoints
矢量和点badPoints
矢量。我想快速得到一组goodPoints
,其中allPoints中的所有内容都不在badPoints中。目前我有:
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++;
}
我觉得这比它应该慢,但我不知道更好的方法。有什么想法吗?
答案 0 :(得分:2)
根据点的尺寸,排序可能不太可行(例如,您只能在一个维度中排序)。更好的方法是拥有一个kD树(例如,如果点在2D中,为点制作2D树结构),这样,您只需要比较所有点,而不是比较所有点。树的叶子。
另一种更简单但不那么优雅的方法是将你的空间划分为一个网格。例如,如果点是2D,则将您的平面划分为NxN网格,并根据您的单元格所在的网格单元格,检查该单元格内部的重叠。您需要使用单元格(或N)的大小来查找单元格数量和单元格内点数之间的平衡。
答案 1 :(得分:1)
如果您的数据未按照评论中的建议进行排序,请使用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;
}
输出:
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
复杂性
2 *(count1 + count2)-1中最多为线性(其中countX为 firstX和lastX之间的距离):比较和分配元素。
答案 2 :(得分:0)
您可以采用的一种方法是利用另一种名为set unique;
的数据结构喜欢而不是int,你的点结构会来。 为简单起见,我正在使用int。
所以你的实现看起来像这样
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);
}
}
希望这有帮助!