我在太空中有两个点,我需要找到点[xmin, ymax]
。我可以使用x然后y在2次传球中完成,但我想在一次传球中完成。
有没有办法可以将这些值组合成一个浮点数,这样我就可以通过一种方式找到正确的点?
我想过做x+y
,但我不知道这是否可靠,很可能不是,如[5,2],[2,5],最后一个会有更高的优先级。< / p>
有什么想法吗?
答案 0 :(得分:3)
您不应对点列表进行排序以查找最大值和最小值,因为这将花费大约O(n * log(n))时间。相反,遍历列表一次,保持对您找到的最高和最低值的引用。这将花费O(n)时间。
min_x = myPoints[0].x;
max_y = myPoints[0].y;
for(Point p in myPoints){
if (p.x < min_x){min_x = p.x;}
if (p.y > max_y){max_y = p.y;}
}
编辑:来自维基百科的格雷厄姆扫描文章:
此算法的第一步是找到y坐标最低的点。如果最低y坐标存在于集合中的多个点中,则应选择候选中具有最低x坐标的点。
因此,分别找到min x和max y是不合适的,因为你要找的那个点可能没有。我们可以修改上面的代码,使用这些新标准。
candidate = myPoints[0];
for (Point p in myPoints){
if (p.y < candidate.y or (p.y == candidate.y and px < candidate.x)){
candidate = p;
}
}
根据您对“最低”的定义,可能有必要将这些“小于”符号中的一些更改为“大于”符号。在某些坐标系中,(0,0)位于图形的左上角,屏幕越低,Y越大。在这种情况下,您应该使用if (p.y > candidate.y
代替
答案 1 :(得分:1)
如果您试图根据词典顺序的某个变体(或者甚至是2D点上的某种其他顺序)找到最小点,那么只需遍历您的一组点,但使用自定义比较来查找/保留最低。以下是C ++中的一个示例,min_element
来自STL,只是一个简单的循环(http://www.cplusplus.com/reference/algorithm/min_element/):
#include <algorithm>
#include <iostream>
using namespace std;
struct Point {
int x, y;
};
struct PointCompare {
bool operator()(const Point& p1, const Point& p2) const {
if (p1.x < p2.x)
return true;
if (p1.x == p2.x)
return p1.y > p2.y; // Your order: xmin then ymax?
//return p1.y < p2.y; // Standard lexicographic order
return false;
}
};
int main()
{
// + 3
// + 4
// + 0
// + 2
// + 1
const Point points[] = {
{ 1, 1 }, // 0
{ 2,-1 }, // 1
{ 0, 0 }, // 2
{ 1, 3 }, // 3
{ 0, 2 }, // 4
};
const Point* first = points;
const Point* last = points + sizeof(points) / sizeof(Point);
const Point* it = min_element(first, last, PointCompare());
cout << it->x << ", " << it->y << endl;
}
答案 2 :(得分:1)
看起来你想要找到一个 max-min 点 - 一个在x坐标最小的点之间具有最大y坐标的点,对吗?
如果是,您可以将所有点存储在STL multimap 中,将x坐标映射到y坐标。此地图将自动排序,并且有可能在此地图中具有最小x坐标的点将只有一个。如果它不是单个点,则可以使用相同(最小)x坐标扫描所有点,以找到具有最大y坐标的点。它仍然需要两次传球,但第二次传球在统计上应该非常短。
如果你真的想要单通道解决方案,那么你可以将你的点存储到STL map ,将x坐标映射到y坐标的 set 。它需要更多的工作,但最终你会得到你的观点 - 你将在地图的开头看到它的x坐标,它的y坐标将在集合的末尾,对应于这个x坐标。
答案 3 :(得分:0)
1.可按排序值排序:x +(MAX * y)或y +(MAX * x)
2.如果你有足够的记忆并且需要极速的速度
像这样对输入点pnt0 []进行排序
for (i=0i<points;i++)
{
x=pnt0[i].x;
y=pnt0[i].y;
pnt[x+(MAX*y)]=pnt[0];
}
如果需要,您可以打包pnt []数组以删除未使用的点,但这可以视为另一个传递