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

Store element in a set with two possible index

本文关键字:两个 索引 集合 存储 元素      更新时间:2023-10-16

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

我的问题是,如何根据终点和起点存储这些线段?我需要为终点和起点生成唯一的编号。(我也愿意接受除使用 stl set :) 之外的任何其他建议(

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

感谢您的任何建议。

您可以保留解决方案或使用operator<。你的优点是切换到一些哈希集实现是微不足道的,另一个应该是更好的实践(更容易理解,可能更快,可以与 64 位坐标一起使用等(。

只需解决您描述的问题(您必须为两个分配执行此操作(,不区分startend而是lowerupper坐标。始终在同一位置使用较小的坐标是一种简单的解决方法,当您以相反的方式发现它们时,可以轻松获得误报不同的线段

只需为线段指定适当的顺序关系运算符即可。 即,如果您的段如下所示:

struct LineSegment {
  int start;
  int end;
};

只需在该结构上定义operator<,以便存在std::less<LineSegment>的实例化(请参阅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>集。线段保证是不同的,当且仅当它们实际上不同时(如果我正确理解了您的问题,这正是您想要的,否则,您可以轻松调整operator<实现(。

同样,如果要在集合中

存储LineSegment*指针,则可以在第二个模板参数中覆盖集合的比较运算符(替换std::less<LineSegment*>(。

一种解决方案是:

    (indexLeft << 32) + indexRight

但是您每次都应该分配左和右。例如,左是具有最小 X 值的那个。

立即想到的一个结构是pair s 的 pair s 的 int s 的set

std::set<std::pair<std::pair<int, int>, std::pair<int, int> > >

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