题
如何定义 operator<
在 n 元组上(例如在 3 元组上),使其满足 严格弱序 概念 ?我知道 boost 库有正确定义的元组类 operator<
但由于某些原因我无法使用它。
解决方案
if (a1 < b1)
return true;
if (b1 < a1)
return false;
// a1==b1: continue with element 2
if (a2 < b2)
return true;
if (b2 < a2)
return false;
// a2 == b2: continue with element 3
if (a3 < b3)
return true;
return false; // early out
此订单由A1是最siginificant和A3至少显著的元素。
这可以继续循环往复,你也可以如它应用到T的矢量,迭代的比较的[I]
当然,如果比较昂贵,你可能想缓存的比较结果。 [编辑]移除错误的代码 [编辑]如果不止while (i<count-1 && !(a[i] < a[i+1]) && !(a[i+1] < a[i])
++i;
return i < count-1 && a[i] < a[i+1];
operator<
是可用的,我倾向于使用图案if (a1 != b1)
return a1 < b1;
if (a2 != b2)
return a2 < b2;
...
其他提示
严格弱序
这是一个数学术语来定义两个对象之间的关系。结果, 其定义是:
两个对象x和y如果两个F(X,y)和F(Y,X)是假的是等效的。需要注意的是,其目的在于始终(由irreflexivity不变),相当于本身。
在C为++。这意味着如果当与操作者相比具有给定类型的两个对象,则应返回下列值<。
X a;
X b;
Condition: Test: Result
a is equivalent to b: a < b false
a is equivalent to b b < a false
a is less than b a < b true
a is less than b b < a false
b is less than a a < b false
b is less than a b < a true
如何定义当量/少完全依赖于你的对象的类型。
形式化定义:结果 严格弱排序
计算机科学:结果 严格弱序
如何,本发明涉及操作符:结果 比较
...一个非常老的问题的新答案,但现有答案错过了 C++11 的简单解决方案...
C++11解决方案
C++11 以后提供 std::tuple<T...>
, ,您可以用它来存储您的数据。 tuple
s 有一个匹配的 operator<
首先比较最左边的元素,然后沿着元组工作,直到结果明确。这适合提供 严格弱序 预期例如 std::set
和 std::map
.
如果您有其他一些变量的数据(例如中的字段 struct
),你甚至可以使用 std::tie()
创建一个元组 参考文献, ,然后可以将其与另一个这样的元组进行比较。这使得写起来很容易 operator<
对于用户定义的特定成员数据字段 class
/struct
类型:
struct My_Struct
{
int a_;
double b_;
std::string c_;
};
bool operator<(const My_Struct& lhs, const My_Struct& rhs)
{
return std::tie(lhs.a_, lhs.b_, lhs.c_) < std::tie(rhs.a_, rhs.b_, rhs.c_);
}
您可以简单地使用三元素向量,这将已经具有操作员<()适当地 定义。这具有使得其延伸到N-元件的优点无需你做任何事情。
的基本流应是沿着线:如果第K个元件是不同的,其返回是较小否则转到下一个元素。下面的代码假设你的不的有升压元组。否则你将使用get<N>(tuple)
并没有开始与问题。
if (lhs.first != rhs.first)
return lhs.first < rhs.first;
if (lhs.second != rhs.second)
return lhs.second< rhs.second;
return lhs.third < rhs.third;
即使你不能使用boost版本,你应该能缺口的代码。我此缺口从标准::对 - 3元组将是相似的我想
。return (_Left.first < _Right.first ||
!(_Right.first < _Left.first) && _Left.second < _Right.second);
编辑:作为一对夫妇的人都指出,如果从标准库窃取代码在代码中使用,你应该改名的事情,对前下划线,因为这些名字是保留