【问题标题】:Is it defined to provide an empty range to C++ standard algorithms?它是否定义为为 C++ 标准算法提供一个空范围?
【发布时间】:2011-09-21 19:08:09
【问题描述】:

my previous question 开始,我们能否证明标准允许我们将空范围传递给标准算法?

第 24.1/7 段将“空范围”定义为范围 [i,i)(其中 i 是有效的),而 i 似乎可以从自身“到达”,但我不确定这有资格作为证明。

特别是,我们在查看排序函数时遇到了麻烦。例如std::sort:

复杂性:O(N log(N))(其中N == last - first)比较

既然log(0)一般被认为是未定义的,我也不知道0*undefined是什么,这里会不会有问题?


(是的,好吧,我有点迂腐。当然,没有自尊的 stdlib 实现会导致传递给std::sort 的空范围的实际问题。但是我想知道这里的标准措辞是否存在潜在漏洞。)

【问题讨论】:

  • 两个 SO 用户需要阅读language-lawyer 标签 wiki:«典型问题涉及“通常在实践中有效的内容”和“规范实际保证的内容”之间的差距。»

标签: c++ c++11 language-lawyer std


【解决方案1】:

Big-O 符号是根据函数的极限来定义的。 实际运行时间g(N)的算法是O(f(N))当且仅当lim N→∞ g(N)/f(N)是一个非负实数 g(N)/f(N)小于某个正实数数字 C 对于所有值 N 大于某个常数 kCk 的确切值无关紧要;您只需要能够找到 any @987654330 @ 和 k 使这一点成为现实)。 (感谢您的更正,杰西!)

您会注意到 实际 元素的数量与大 O 分析无关。 Big-O 分析没有说明算法对少量元素的行为。因此,f(N) 是否在N=0 中定义并不重要。更重要的是,实际运行时行为由一个不同函数g(N)控制,即使f(0)未定义,它也可能在N=0中定义。 p>

【讨论】:

  • 好的,所以复杂性要求没有问题,我们可以依靠范围满足所有规定的迭代器要求这一事实?
  • 对不起,因为我没有标准的副本,所以我无法理解标准的措辞。
  • 好的;这就是我所追求的,真的。
  • 要学究气(因为 OP 也是 :),Big-O 表示法不是极限; g(N)O(f(N)) 在范围内 I 如果有一些正常数C 使得g(N) <= C f(N) 对于I 中的所有N。因此,如果标准愿意的话,关于N = 0 真的有要说的。 (并且可以将I 的范围替换为“for large N”,意思是[N_0, infinity) 存在一定的范围,这大概就是标准所指的复杂度)
  • 顺便说一下,我试图画出的主要区别是g(N)/f(N) 的限制可能不存在(它只需要有一个上限)。
【解决方案2】:

我似乎没有多少可以提问的余地。在 §24.1/6 中,我们被告知:

当且仅当存在使 i == j 的表达式 ++i 的有限应用序列时,迭代器 j 被称为从迭代器 i 可达。

24.1 美元/7 美元:

范围 [i, j) 当且仅当 j 可从 i 到达时才有效。

由于0 是有限的,[i, i) 是一个有效范围。 §24.1/7 继续说:

将库中的函数应用于无效范围的结果是 未定义。

这并不能说有效范围保证了定义的结果(合理,因为还有其他要求,例如比较函数),但肯定似乎暗示范围本身是空的,不应该导致UB或类似的东西。然而,特别是,该标准使空范围成为另一个有效范围。空有效范围和非空有效范围之间没有真正的区别,因此适用于非空有效范围的内容同样适用于空有效范围。

【讨论】:

  • 确实如此。我认为到目前为止,您的回答与我的结论一致,而且似乎与我能想到的任何事情一样彻底。
【解决方案3】:

除了@bdonlan 给出的相关答案外,还要注意f(n) = n * log(n) 确实有一个明确定义的限制,因为n 变为零,即0。这是因为对数的发散速度比任何多项式都慢,特别是比n 慢。所以一切都很好:-)

【讨论】:

  • 但是,例如lower_bound 仍然存在问题,其复杂性要求是“最多log2(last-first) + O(1) 比较”。这不对对数部分使用 O 表示法,因此 @bdonlan 的论点不适用;并且log2(n) 没有限制,因为n 变为零。我们在这里能做的最好的事情就是争辩 log2(0) 是否定的(即使它是未定义的),并且(如果我们谈论的是 C++11)调用 17.5.1.4/6(“如果复杂性要求的制定调用对于负数的操作,实际要求是零操作。")
  • @Mike:好的,很公平,尽管实际上一开始当然没有任何问题,因为大 O 表示法描述的是渐近行为,所以任何有界区间上的行为都是无关紧要的。不过,感谢您指出这一点:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
  • 2013-08-27
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
  • 2020-08-17
  • 2012-06-04
相关资源
最近更新 更多