我需要针对特定情况的解决方案。我有一个基本上适用于线段的算法。我只知道线段结束和起点。 (点有2个坐标x,y。这些是图像上的像素点。我也知道图像的大小。)我想检查这些线段并对它们做一些事情。但是,我还需要跟踪检查的线段,以便我不再检查相同的线段。我正在使用C ++,所以我想使用stl set container。
我的问题是如何根据它们的结束点和起点存储这些线段?我需要为结束点和起点生成唯一的数字。 (除了使用stl set之外,我还可以接受任何其他建议:))
一种可能的解决方案是我通过以下方式为这两个像素生成索引号:(y * image-> Witdh)+ x。然后我得到两个索引号(顺便说一下它们是整数。)然后我将这些数字连接起来:(indexStart<< 32)+ indexEnd。(我得到双倍)。现在我有唯一的号码,我可以很容易地存储在集合中。但问题是在我的搜索中,一旦线段的起点可以是同一线段的终点。如果我从端点遇到相同的线段,则连接的线段唯一编号变为(indexEnd<< 32)+ indexStart。然后我将相同的线段添加到我需要避免的set容器中。
感谢您的任何建议。
答案 0 :(得分:1)
只需为您的线段指定正确的订单关联运算符即可。即如果你的细分看起来像这样:
struct LineSegment {
int start;
int end;
};
只需在该结构上定义operator<
,以便存在std::less<LineSegment>
的实例化(请参阅definition of set了解为什么这很重要)。
bool operator<(LineSegment const& lhs, LineSegment const& rhs) {
if (lhs.start == rhs.start)
return lhs.end < rhs.end;
return lhs.start < rhs.start;
}
这允许您使用std::set<LineSegment>
集合,这些集合遵循正确的顺序。 LineSegments保证是不同的,当且仅当它们实际上不同时(如果我正确理解你的问题,这正是你想要的,否则,你可以很容易地调整operator<
实现)。
同样,如果要在集合中存储std::less<LineSegment*>
指针,可以在第二个模板参数中覆盖集合的比较运算符(替换LineSegment*
)。
答案 1 :(得分:1)
一个解决方案是:
(indexLeft << 32) + indexRight
但你应该每次分配左和右。例如,Left是具有最小X值的那个。
答案 2 :(得分:1)
您可以保留解决方案或使用operator<
。你的优点是切换到一些hashset实现是微不足道的,另一个应该是更好的整体练习(更容易理解,可能更快,可以使用64位坐标等)。
通过不区分start
和end
但lower
和upper
坐标来解决您描述的问题(您必须为两个apporaches执行此操作)。总是在同一个地方使用较小的坐标是一个简单的方法,当你以相反的方式发现它们时获得误报的不同段
答案 3 :(得分:0)
立即想到的一个结构是set
pair
个pair
int
个std::set<std::pair<std::pair<int, int>, std::pair<int, int> > >
的{{1}}个:
{{1}}
这样每个键都有一个明确唯一的值,并描述了一个完整的线段。