【发布时间】:2010-11-20 13:31:26
【问题描述】:
为什么 STL 可以使用 strict weak ordering 的比较函数?为什么不能是偏序?
【问题讨论】:
-
你不能澄清一下展示样本是什么意思吗?
标签: c++ algorithm stl strict-weak-ordering
为什么 STL 可以使用 strict weak ordering 的比较函数?为什么不能是偏序?
【问题讨论】:
标签: c++ algorithm stl strict-weak-ordering
partial order 不足以实现某些算法,例如排序算法。由于偏序集合不一定定义集合的所有元素之间的关系,那么您将如何对在偏序内没有顺序关系的两个项目的列表进行排序?
【讨论】:
简单地说,严格的弱排序被定义为定义(可计算的)等价关系的排序。等价类按严格弱序排序:严格弱序是对等价类的严格排序。
偏序(不是严格的弱序)没有定义等价关系,所以任何使用“等价元素”概念的规范对于非严格弱序的偏序都是没有意义的。 所有 STL 关联容器在某些时候都使用这个概念,所以所有这些规范对于不是严格弱排序的部分排序是没有意义的。
因为偏序(不是严格的弱序)不一定定义任何严格的序,所以不能按照偏序对常识中的元素进行“排序”(只能做“拓扑排序”具有较弱的属性)。
给定
S
< 对 S 的部分排序
x 中的值 S
您可以定义S 的分区(S 的每个元素都在L(x)、I(x) 或G(x) 中):
L(x) = { y in S | y<x }
I(x) = { y in S | not(y<x) and not(x<y) }
G(x) = { y in S | x<y }
L(x) : set of elements less than x
I(x) : set of elements incomparable with x
G(x) : set of elements greater than x
一个序列按照<排序 iff 对于序列中的每个x,L(x)的元素在序列中首先出现,然后是I(x)的元素,然后是G(x) 的元素。
对于序列中出现在另一个元素x 之后的每个元素y,对序列进行拓扑排序iff,y 不小于x。这是一个比排序更弱的约束。
证明L(x) 的每个元素都小于G(x) 的任何元素是微不足道的。 L(x) 的元素与I(x) 的元素之间或I(x) 的元素与G(x) 的元素之间没有一般关系。但是,如果< 是严格的弱排序,则L(x) 的每个元素都小于I(x) 的任何元素,并且I(x) 的任何元素都小于G(x) 的任何元素。
如果< 是严格的弱排序,并且x<y 则L(x) U I(x) 的任何元素都小于I(y) U G(y) 的任何元素:不大于x 的任何元素小于不小于@ 的任何元素987654357@。 这不一定适用于部分排序。
【讨论】:
I(x) 是一个集合(S 的一部分); I(x) < x 的意思是:对于每个 y,这是 I(x)、y < x 的一个元素?如果是这样,not(x < E) and not(E < x)(其中x 是S 的一个元素,E 是S 的一部分)并不意味着E = {x}。
引用here给出的答案:
因为在内部,这些算法将“等于”实现为
!(a < b) && !(b < a)。如果你使用
<=来实现小于运算符,那么上面 当a == b时将返回 false。被破坏的平等检查会搞砸 几乎任何算法。同样,他们将“不等于”实现为
(a < b) || (b < a),再一次,如果您使用<=实现了<运算符,那么它 当它们彼此相等时将返回 true,而实际上它们 不相等。所以相等性检查在两个方向上都被破坏了。将库限制为小于运算符的全部意义在于 所有的逻辑运算符都可以用它来实现:
<(a, b):(a < b)<=(a, b):!(b < a)==(a, b):!(a < b) && !(b < a)!=(a, b):(a < b) || (b < a)>(a, b):(b < a)>=(a, b):!(a < b)只要您提供的运算符满足 严格的弱排序。标准的
<=和>=运算符不支持。
【讨论】:
您不能使用偏序执行二分查找。您不能创建具有偏序的二叉搜索树。 算法中的哪些函数/数据类型需要排序并且可以使用部分排序?
【讨论】: