将元素存储在具有两个可能索引的集合中

时间:2012-05-07 12:49:13

标签: c++ algorithm stl

我需要针对特定​​情况的解决方案。我有一个基本上适用于线段的算法。我只知道线段结束和起点。 (点有2个坐标x,y。这些是图像上的像素点。我也知道图像的大小。)我想检查这些线段并对它们做一些事情。但是,我还需要跟踪检查的线段,以便我不再检查相同的线段。我正在使用C ++,所以我想使用stl set container。

我的问题是如何根据它们的结束点和起点存储这些线段?我需要为结束点和起点生成唯一的数字。 (除了使用stl set之外,我还可以接受任何其他建议:))

一种可能的解决方案是我通过以下方式为这两个像素生成索引号:(y * image-> Witdh)+ x。然后我得到两个索引号(顺便说一下它们是整数。)然后我将这些数字连接起来:(indexStart<< 32)+ indexEnd。(我得到双倍)。现在我有唯一的号码,我可以很容易地存储在集合中。但问题是在我的搜索中,一旦线段的起点可以是同一线段的终点。如果我从端点遇到相同的线段,则连接的线段唯一编号变为(indexEnd<< 32)+ indexStart。然后我将相同的线段添加到我需要避免的set容器中。

感谢您的任何建议。

4 个答案:

答案 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位坐标等)。

通过不区分startendlowerupper坐标来解决您描述的问题(您必须为两个apporaches执行此操作)。总是在同一个地方使用较小的坐标是一个简单的方法,当你以相反的方式发现它们时获得误报的不同段

答案 3 :(得分:0)

立即想到的一个结构是set pairpair intstd::set<std::pair<std::pair<int, int>, std::pair<int, int> > >的{​​{1}}个:

{{1}}

这样每个键都有一个明确唯一的值,并描述了一个完整的线段。