C++ std::strong_ordering

2025年3月21日 | 阅读 7 分钟

在现代 C++(从 C++20 开始)中,通过三向比较的概念(通常称为“飞船运算符”(<=>))引入了一种强大而直观的比较对象和值的方法。此运算符允许您比较两个对象并获得一个描述比较结果的单一值。比较结果可以分为几个类别,例如小于、等于或大于。

由 <=> 运算符 返回的类型之一是 std::strong_ordering。理解 std::strong_ordering 是在 C++ 中充分利用三向比较的关键。

std::strong_ordering 的属性

  • 全序关系:任意两个值都可以进行比较,并且比较是明确的。这意味着对于任意两个值 a 和 b,std::strong_ordering 将明确指出 a < b、a == b 或 a > b。
  • 反对称性:如果 a < b 为真,则 b > a 也必须为真。如果 a == b,则 b == a。
  • 传递性:如果 a < b 且 b < c,则 a < c。类似地,如果 a == b 且 b == c,则 a == c。

方法 1:简单方法

实施

输出

 
a is less than b   

说明

1. 程序初始化

程序通过设置执行环境来启动。这包括必要的库和定义执行开始的 main 函数

2. 变量声明

声明并初始化两个变量 a 和 b,并赋予它们特定的整数值。在此示例中,假设 a 为 15,b 为 25。这些值代表我们将要比较的数据。

3. 比较操作

代码的核心是两个变量 a 和 b 之间的比较。这通过一系列条件语句来实现

  • 小于比较:首先,代码检查 a 是否小于 b。这是一个直接的比较,用于检查 15(a 的值)是否小于 25(b 的值)。如果此条件为真,则意味着 a 确实小于 b。
  • 相等性检查:如果第一个条件(小于)无效,代码将检查 a 是否等于 b。第二个条件评估 15 是否等于 25。如果此条件为真,则两个 变量都相等。
  • 大于检查:如果前两个条件都不为真,代码将假定 a 必须大于 b。最后一个条件检查 15 是否大于 25。

4. 输出结果

根据比较结果

  • 如果第一个条件(小于)为真,程序将打印一条消息,指示 a 小于 b。
  • 如果相等性检查准确,则打印一条消息,指示 a 等于 b。
  • 如果前两个条件都不满足,则打印一条消息,指示 a 大于 b。

5. 程序终止

根据比较结果打印后,程序将结束执行。当所有指令都执行完毕并显示输出后,程序就有效地结束了。

复杂度分析

时间复杂度

常数时间操作:比较操作(<、==、>)是常数时间操作。它们花费的时间与 a 和 b 的值无关。每次比较所需的时间为 O(1),因为它涉及单个、直接的算术运算。

条件检查:一系列条件检查(小于、相等、大于)也以常数时间执行。每次检查都涉及比较两个值,这是一个固定时间操作。

总体时间复杂度:由于所有操作都执行固定次数(具体来说是三次比较和一次输出操作),因此代码的总体时间复杂度为 O(1)。这意味着执行时间不取决于输入大小,而是保持不变。

空间复杂度

变量存储:代码使用固定数量的内存来存储变量 a、b 以及比较结果。这些变量是整数,需要恒定的空间,与它们的值无关。

无额外数据结构:代码不使用任何会随输入大小增长的额外数据结构(如 数组对象)。它仅执行比较并打印结果,这些不需要额外的内存。

总体空间复杂度:存储几个整数和执行比较所需的空间是恒定的。因此,代码的总体空间复杂度为 O(1)。

方法 2:使用自定义枚举

自定义枚举方法是一种使用用户定义的枚举来处理值之间比较的方法。这种方法通过定义一组表示比较结果的命名常量来增强代码的可读性和可维护性。该方法不依赖于原始比较运算符(有时不够直观),而是使用枚举来清晰地指示一个值是否小于、等于或大于另一个值。

实施

输出

 
a is less than b   

说明

1. 程序设置

程序开始准备执行的必要环境。这包括导入必要的库和定义程序逻辑将执行的主函数。

2. 定义枚举

创建一个枚举(通常称为 enum),用于表示比较的结果。此枚举有三个不同的值:

  • Less(小于):表示一个值小于另一个值。
  • Equal(等于):表示两个值相同。
  • Greater(大于):表示一个值大于另一个值。

通过定义此枚举,我们为比较的可能结果提供了有意义的名称,使代码更易于阅读和理解。

3. 比较函数

定义一个专用函数来处理两个值之间的比较逻辑。此函数使用条件语句来确定这两个值如何相互关联。

  • 小于检查:函数首先检查第一个值是否小于第二个值。如果为真,则返回枚举中的 Less 值。
  • 相等性检查:如果值不小于,函数将检查它们是否相等。如果为真,则返回枚举中的 Equal 值。
  • 大于检查:如果前两个条件都不为真,函数将假定第一个值必须更大,并返回枚举中的 Greater 值。

4. 使用比较结果

在主函数中,使用两个特定值调用比较函数。此比较的结果存储在一个变量中。

  • Switch 语句:然后使用 switch 语句对结果(一个枚举值)进行求值。此语句有助于根据枚举值做出决策。
  • Less:如果结果是 Less,则表示第一个值小于第二个值,程序将打印相应的消息。
  • Equal:如果结果是 Equal,则表示两个值相同,程序将打印一条反映这种相等性的消息。
  • Greater:如果结果是 Greater,则表示第一个值大于第二个值,程序将打印相应的消息。

5. 程序终止

处理完比较结果并打印消息后,程序将结束执行。一旦所有语句都执行完毕并显示输出,程序就会退出。

复杂度分析

1. 时间复杂度

比较函数:执行两个值(a 和 b)之间比较的函数涉及固定数量的操作。它执行三个条件检查:小于、相等和大于。每次检查都是常数时间操作,意味着它花费的时间与 a 和 b 的值无关。

Switch 语句:在从比较函数获得结果后,switch 语句将对枚举值进行求值。Switch 语句也是常数时间操作,因为它涉及固定数量的情况。

总体时间复杂度:由于操作次数不取决于输入大小,并且执行次数固定,因此自定义枚举方法的总体时间复杂度为 O(1)。这表明执行时间保持不变。

2. 空间复杂度

变量存储:该方法使用固定量的内存来存储几个整数值和比较结果。枚举本身的大小是恒定的,不会根据输入大小而改变。

枚举存储:枚举定义了一组小型、固定的命名常量。存储这些常量所需的空间可以忽略不计,并且不会随输入大小而增长。

函数开销:用于比较的函数具有固定的内存占用空间,因为它只涉及基本操作,并且不使用额外的动态内存。

总体空间复杂度:内存使用是恒定的,并且不取决于输入大小。因此,自定义枚举方法的总体空间复杂度为 O(1)。