繁体   English   中英

C++ map lower_bound/upper_bound

[英]C++ map lower_bound/upper_bound

我了解mapC++的底层数据结构是一个自平衡二叉搜索树。 由于在这些数据结构中,找到键的下限和上限有很多用途,您可能会认为 map 的 lower_bound 和 upper_bound 函数将为您提供这种能力。 令人遗憾的是,这些功能无法实现这一点。 有谁知道为什么 lower_bound 的行为方式如此? (它为您提供不在给定密钥之前的密钥)。

这不仅在 map 中。 它位于 STL 中。

您的xlower_bound找到x <= y y 和上upper_bound x < y

自从 SGI 推出 STL 之前,我就一直在使用 C++,并且由于某种原因仍然设法弄乱了使用这些方法,包括在将它们呈现给 ZA2F2ED4F8EBC2CABBB4C21A2DC 时甚至让自己感到尴尬。 我认为我的问题是:

  1. 这些名称在数学中已经具有直观但不同的含义。 鉴于数学含义,在一个大集合或 map 中, upper_boundlower_bound实际上是相同或相邻的元素似乎很奇怪。

  2. “upper_bound”和“lower_bound”这两个名字听起来好像两者之间存在某种对称性,但绝对没有。 如果名称类似于lower_bound 的least_ge (最小大于或等于)和upper_bound 的least_gt (最小大于),我会轻松得多。

如果有人有助记符或逻辑使这些易于内化,请分享。 否则,感觉就像他们写了两个有用的函数,但使用了两个随机的数学术语来命名这些函数,无法从名称中推导出语义。 到那时,为什么不使用像egptrpbase这样的虚构名称呢? 我的意思是至少我没有任何预先存在的直觉来克服streambuf方法的名称......

无论如何,我认为这是您必须记住的基本规则:

  • lower_bound(X)返回满足v >= X的最低元素v

  • upper_bound(X)返回满足v > X的最低元素v

  • 要遍历半开区间 [L,H),从lower_bound(L)开始并在(不处理) lower_bound(H)处停止。 这通常是您想要的,因为在 C++ 中遍历半开区间是最常见的——例如,[ buf , buf+nbytes ) 或 [ 0 , array_size ) 或 [ begin() , end() )。

  • 要遍历闭区间 [L,H],从lower_bound(L)开始,在upper_bound(H)停止。

  • 要遍历开区间 (L,H),从upper_bound(L)开始,在lower_bound(H)停止。

  • 在非空容器中, lower_bound(X)的镜像是std::prev(upper_bound(X))upper_bound(X) (X) 的镜像是std::prev(lower_bound(X)) 当然,如果一个元素等于begin() ,那么你不能用std::prev将它倒退,所以你需要额外的逻辑来处理这个点不能用迭代器值表示的事实。

  • 在多重集/多重映射中,如果该元素确实是v ,则第一个vlower_bound(v) 如果容器不为空且该元素为v ,则最后一个vstd::prev(upper_bound(v)) ,但请记住在尝试prev on end()之前检查容器是否为空。

从通常的数学约定的角度来看, upper_bound是“最不真实的上界”(永远不相等),而lower_bound是“最小的上界”(可能相等)。 在通常的数学约定中, lower_bound实际上是“上限”这一事实可能会导致用户混淆。

一种使lower_bound / upper_bound名称合理化的方法是在另一种称为equal_range的方法的上下文中考虑它们。 lower_bound实际上是equal_range的“lower_bound”,与upper_bound类似。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM