C++ 如何删除最接近的“;“点”;STD::列表中的对象到某个x,y?
我有一个point类,如:C++ 如何删除最接近的“;“点”;STD::列表中的对象到某个x,y?,c++,list,pointers,distance,C++,List,Pointers,Distance,我有一个point类,如: class Point { public: int x, y; Point(int x1, int y1) { x = x1; y = y1; } }; 以及一系列要点: std::list <Point> pointList; std::list <Point>::iterator iter; std::list pointList; 标准::列表::迭代器iter; 我正
class Point {
public:
int x, y;
Point(int x1, int y1)
{
x = x1;
y = y1;
}
};
以及一系列要点:
std::list <Point> pointList;
std::list <Point>::iterator iter;
std::list pointList;
标准::列表::迭代器iter;
我正在将点推送到我的点列表中(尽管如果还没有推送点,列表可能还没有包含点)
我有两个问题:
如何从列表中删除与任意点(x,y)最近的点?
假设我有x,y(5,12),我想在列表中找到最接近该点的点,并将其从STD::列表中删除
我知道我必须使用距离公式,我必须使用迭代器在列表中迭代,但是我在概念化如何在迭代列表时跟踪哪个点最接近时遇到了一些问题
如何返回给定(x,y)的x半径内的数组或点列表?
与上一个问题类似,只是我需要一个指向给定(x,y)半径5内的“点”对象的指针列表。另外,我应该返回数组还是列表
如果有人能帮助我,我仍在努力克服C++,我很感激。< / P >你对它应该如何做是正确的。只需遍历列表中的所有项目,并跟踪已找到的最小距离,以及在两个变量中找到的最近点,如果问题出现,请确保该点与自身不匹配。然后删除你找到的点 这到底是如何制作的,这是一个练习 如果要从另一个点获取给定半径内的点列表,请迭代该列表并构建第二个列表,其中仅包含指定范围内的点
同样,它是如何在代码中生成的,留给您作为练习。在循环列表时,使用std::list::iterator变量跟踪最近的点。当您到达列表的末尾时,它将包含最近的点,并可用于删除该项
void erase_closest_point(const list<Point>& pointList, const Point& point)
{
if (!pointList.empty())
{
list<Point>::iterator closestPoint = pointList.begin();
float closestDistance = sqrt(pow(point.x - closestPoint->x, 2) +
pow(point.y - closestPoint->y, 2));
// for each point in the list
for (list<Point>::iterator it = closestPoint + 1;
it != pointList.end(); ++it)
{
const float distance = sqrt(pow(point.x - it->x, 2) +
pow(point.y - it->y, 2));
// is the point closer than the previous best?
if (distance < closestDistance)
{
// replace it as the new best
closestPoint = it;
closestDistance = distance
}
}
pointList.erase(closestPoint);
}
}
void擦除最近点(常数列表和点列表,常数点和点)
{
如果(!pointList.empty())
{
列表::迭代器closestPoint=pointList.begin();
浮动闭合距离=sqrt(pow(点x-闭合点->x,2)+
功率(点y-闭合点->点y,2);
//对于列表中的每个点
对于(list::iterator it=closestPoint+1;
it!=pointList.end();+it)
{
常量浮动距离=sqrt(pow(点x-it->x,2)+
pow(point.y-it->y,2));
//这一点比之前的最佳点更接近吗?
if(距离<最近距离)
{
//换成新的最好的
closestPoint=it;
最近距离=距离
}
}
点列表。擦除(关闭点);
}
}
在给定点的半径内构建点列表类似。请注意,空半径列表通过引用传递到函数中。通过引用将点添加到列表将消除在按值返回向量时复制所有点的需要
void find_points_within_radius(vector<Point>& radiusListOutput,
const list<Point>& pointList,
const Point& center, float radius)
{
// for each point in the list
for (list<Point>::iterator it = pointList.begin();
it != pointList.end(); ++it)
{
const float distance = sqrt(pow(center.x - it->x, 2) +
pow(center.y - it->y, 2));
// if the distance from the point is within the radius
if (distance > radius)
{
// add the point to the new list
radiusListOutput.push_back(*it);
}
}
}
void查找半径内的点(向量和半径列表输出,
常量列表和点列表,
常量点和中心、浮动半径)
{
//对于列表中的每个点
for(list::iterator it=pointList.begin();
it!=pointList.end();+it)
{
常量浮动距离=sqrt(功率(center.x-it->x,2)+
pow(center.y-it->y,2));
//如果与点的距离在半径范围内
如果(距离>半径)
{
//将该点添加到新列表中
radiusListOutput.push_back(*it);
}
}
}
如果出现以下情况,请再次使用“复制”:
struct RadiusChecker {
RadiusChecker(const Point& center, float radius)
: center_(center), radius_(radius) {}
bool operator()(const Point& p)
{
const float distance = sqrt(pow(center_.x - p.x, 2) +
pow(center_.y - p.y, 2));
return distance < radius_;
}
private:
const Point& center_;
float radius_;
};
void find_points_within_radius(vector<Point>& radiusListOutput,
const list<Point>& pointList,
const Point& center, float radius)
{
radiusListOutput.reserve(pointList.size());
remove_copy_if(pointList.begin(), pointList.end(),
radiusListOutput.begin(),
RadiusChecker(center, radius));
}
struct RadiusChecker{
半径检查器(常数点和中心、浮动半径)
:中心(中心),半径(半径){}
布尔运算符()(常数点和p)
{
常量浮动距离=sqrt(功率(中心x-p.x,2)+
战俘(中卫-p.y,2);
返回距离<半径;
}
私人:
常数点和中心点;
浮动半径;
};
void查找半径内的点(向量和半径列表输出,
常量列表和点列表,
常量点和中心、浮动半径)
{
reserve(pointList.size());
如果(pointList.begin(),pointList.end(),则删除\u copy\u,
radiusListOutput.begin(),
半径切割器(中心、半径);
}
请注意,如果需要额外的性能,可以删除sqrt,因为数量级的平方对于这些比较同样有效。此外,如果你真的想提高性能,而不是考虑一个允许场景分割的数据结构。第一个问题与该主题密切相关,并且有大量关于该主题的有价值信息可用。您必须保留迭代器以在之后删除它
std::list<Point>::iterator closest;
std::list<Point>::iterator it = pointList.begin();
double min_dist=dist(your_point, *it);
++it;
for (; it != pointList.end(); ++it)
{
double actual_dist = dist(your_point, *it);
if (actual_dist < min_dist)
{
min_dist = actual_dist;
closest = it;
}
}
pointList.erase(closest);
std::list::迭代器最近;
std::list::iterator it=pointList.begin();
double min_dist=距离(您的点,*it);
++它;
for(;it!=pointList.end();++it)
{
双倍实际距离=距离(你的点,*it);
if(实际距离<最小距离)
{
最小距离=实际距离;
最近的=它;
}
}
点列表。擦除(最近的);
我同意前面的解决方案,只是想添加另一个想法。虽然你的点类不是很大,所以一个拷贝并不是一个问题,你可以考虑使用点*来进行列表。这样,当您创建第二个列表时,您将存储指向同一类的指针。不利的一面是,如果您从多个列表中删除时没有管理所有创建点的“主”列表,则如果您不删除该列表,则可能会造成内存泄漏
#include <list>
#include <cmath>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/bind.hpp>
#include <cassert>
using namespace std;
using namespace boost;
struct Point {
int x, y;
Point() : x(0), y(0) {}
Point(int x1, int y1) : x(x1), y(y1) {}
Point(Point const & other) : x(other.x), y(other.y) {}
Point & operator=(Point rhs) { rhs.swap(*this); return *this; }
void swap(Point & other) { std::swap(other.x, x); std::swap(other.y, y); }
};
double point_distance(Point const & first, Point const & second) {
double x1 = first.x;
double x2 = second.x;
double y1 = first.y;
double y2 = second.y;
return sqrt( ((x2 - x1) * (x2 -x1)) + ((y2 - y1) * (y2 - y1)) );
}
int main(int argc, char * argv[]) {
list<Point> points;
points.push_back(Point(1, 1));
points.push_back(Point(2, 2));
points.push_back(Point(3, 3));
Point source(0, 0);
list<Point>::const_iterator closest =
min_element(
make_transform_iterator(
points.begin(),
bind(point_distance, source, _1)
),
make_transform_iterator(
points.end(),
bind(point_distance, source, _1)
)
).base();
assert(closest == points.begin());
return 0;
}