一个结构中的多个点的运算符
Operator for Multiple Points in One Struct
我有一个存储两个应该可以互换的点的结构。
struct Edge
{
unsigned short firstIndex;
unsigned short secondIndex;
Edge(unsigned short firstIndex, unsigned short secondIndex) :
firstIndex(firstIndex), secondIndex(secondIndex) {}
};
operator==
方法应该如下(为了使它们可以互换)
bool operator == (const Edge& e2) const
{
return
first == e2.first && second == e2.second ||
first == e2.second && second == e2.first;
}
我想创建一个 operator<
和 operator>
方法以便在 std::map
[=25= 中使用该结构]
我尝试了以下方法(使用乘法)但它不起作用,因为在很多情况下不同的边 return 相同的值
bool operator < (const Edge& e2) const
{
return first * second < e2.first * e2.second;
}
我想使用的代码如下:
std::map<Edge, unsigned int> edgePoints;
Edge e1(0, 1);
Edge e2(1, 2);
Edge e3(2, 0);
edgePoints[e1] = 2;
edgePoints[e2] = 0;
edgePoints[e3] = 1;
尽管代码不适用于我的 operator<
方法,因为 0 * 1 == 2 * 0
所以当我调用 edgePoints[e3]
[=25 时映射 returns 2
=]
有谁知道我可以使用的 operator<
和 operator>
方法,甚至是其他映射边缘的方法,以便使用 std::map
考虑将它们作为排序对进行比较。
bool operator < (const Edge& e2) const
{
if (min(first, second) != min(e2.first, e2.second))
return min(first, second) < min(e2.first, e2.second);
return max(first, second) < max(e2.first, e2.second);
}
编辑:当然,将最小值和最大值保存为局部变量可以写得更好,但思路应该很清楚。
编辑:其他答案中的想法更好:强制您的结构始终具有第一个小于第二个,这将消除所有最小值和最大值,并使比较 运行 非常快)
我会以这样一种方式存储边的索引,即较小的索引始终是第一个索引。看起来内部表示与您的应用程序无关。地图不需要 operator==
。这是示例结构:
struct Edge
{
typedef unsigned short Idx; // prefer strong typedef cf boost
Edge(Idx a, Idx b)
:
firstIndex(std::min(a, b)),
secondIndex(std::max(a, b))
{}
Idx firstIndex;
Idx secondIndex;
bool operator<(Edge const & other)
{
if (firstIndex != other.firstIndex)
return firstIndex < other.firstIndex;
return secondIndex < other.secondIndex;
}
}; // Edge
如果你想让你的实现更好,一些小建议:
- 优先选择
std::array<unsigned short, 2>
而不是单独的变量 firstIndex
和 secondIndex
。这样做允许迭代索引。
- 如果您使用
array
,您可以使用 std::lexicographical_compare
缩短 operator<
。
我有一个存储两个应该可以互换的点的结构。
struct Edge
{
unsigned short firstIndex;
unsigned short secondIndex;
Edge(unsigned short firstIndex, unsigned short secondIndex) :
firstIndex(firstIndex), secondIndex(secondIndex) {}
};
operator==
方法应该如下(为了使它们可以互换)
bool operator == (const Edge& e2) const
{
return
first == e2.first && second == e2.second ||
first == e2.second && second == e2.first;
}
我想创建一个 operator<
和 operator>
方法以便在 std::map
[=25= 中使用该结构]
我尝试了以下方法(使用乘法)但它不起作用,因为在很多情况下不同的边 return 相同的值
bool operator < (const Edge& e2) const
{
return first * second < e2.first * e2.second;
}
我想使用的代码如下:
std::map<Edge, unsigned int> edgePoints;
Edge e1(0, 1);
Edge e2(1, 2);
Edge e3(2, 0);
edgePoints[e1] = 2;
edgePoints[e2] = 0;
edgePoints[e3] = 1;
尽管代码不适用于我的 operator<
方法,因为 0 * 1 == 2 * 0
所以当我调用 edgePoints[e3]
[=25 时映射 returns 2
=]
有谁知道我可以使用的 operator<
和 operator>
方法,甚至是其他映射边缘的方法,以便使用 std::map
考虑将它们作为排序对进行比较。
bool operator < (const Edge& e2) const
{
if (min(first, second) != min(e2.first, e2.second))
return min(first, second) < min(e2.first, e2.second);
return max(first, second) < max(e2.first, e2.second);
}
编辑:当然,将最小值和最大值保存为局部变量可以写得更好,但思路应该很清楚。
编辑:其他答案中的想法更好:强制您的结构始终具有第一个小于第二个,这将消除所有最小值和最大值,并使比较 运行 非常快)
我会以这样一种方式存储边的索引,即较小的索引始终是第一个索引。看起来内部表示与您的应用程序无关。地图不需要 operator==
。这是示例结构:
struct Edge
{
typedef unsigned short Idx; // prefer strong typedef cf boost
Edge(Idx a, Idx b)
:
firstIndex(std::min(a, b)),
secondIndex(std::max(a, b))
{}
Idx firstIndex;
Idx secondIndex;
bool operator<(Edge const & other)
{
if (firstIndex != other.firstIndex)
return firstIndex < other.firstIndex;
return secondIndex < other.secondIndex;
}
}; // Edge
如果你想让你的实现更好,一些小建议:
- 优先选择
std::array<unsigned short, 2>
而不是单独的变量firstIndex
和secondIndex
。这样做允许迭代索引。 - 如果您使用
array
,您可以使用std::lexicographical_compare
缩短operator<
。