为什么c++算法包含最多2*(count1+count2)-1的比较

why c++ algorithm includes have at most 2*(count1+count2)-1 comparisons

本文关键字:count1+count2 比较 算法 c++ 包含最 为什么      更新时间:2023-10-16

在阅读cplusplus.com的一篇文章时,我注意到它说了以下内容:

两个范围内距离的两倍以内为线性:执行最多2*(count1+count2)-1比较(其中countX是firstX和lastX之间的距离)。

然而,cppreference.com指出:

最多2·(N1+N2-1)比较,其中N1=std::distance(first1,last1)和N2=std:;distance(first2,last2)。

根据定义,N1==Count1和N2==Count2,哪个站点是正确的,谁能解释这个最大数量或比较是如何计算的,即:

  1. 定义这种最大复杂性的最坏情况是什么
  2. 有人能解释一下该场景中的步骤,并说明上面哪一个(cplusplus或cpprreference)具有正确的比较次数吗

警告:在所有阅读过该帖子的人(包括我)意识到他们不知道自己在说什么之前,这个答案的声誉就已经增加了。如果在未来的某个时候,有一个公认的答案与该算法的所有文档都不一致,请更加注意!

简而言之:

2*(任意)位很容易解释,我已经在下面做了解释。这一点让我非常困惑,据我所知,这应该是

2*(count1)

并且与第二范围的长度完全无关。要么我遗漏了什么(很可能),要么文档有误(这不是很好吗…)

如果你想要我的推理,请参阅下文。如果我错了,有人回答对了,请告诉我,这样我就可以删除这篇帖子了!

为什么是2*(计数1等)

如果你问为什么是2次(count1+count2)-1,关键在这一行:

使用运算符<对于第一个版本,comp用于第二个版本。如果(!(a<b)&amp!(b<a))或者如果(!comp(a&comp(b,a))。

每次它比较两个元素时,都会进行两次比较:我不等于它吗?它不等于我吗?

最大这些";比较对";它要做的是非常难以确定。事实上,我想不通。据我所知,这应该与第二范围的长度无关。。。

为什么不是(count1+count2-1)或(count1+count 2)-1

我已经研究了好几天了,并根据cpprreference中的代码示例进行了一些测试,老实说,我不知道这怎么可能是真的。

这些算法意味着,OP挖掘的一个来源说range2必须是range1的子集,并且两者都是排序的,所以没有必要对一个元素进行两次检查。这意味着算法最多必须检查range1的所有元素,如果range2的元素大于range1中的任何元素,则需要额外检查一次。不仅如此,范围2中哪里有2或20个元素并不重要,它仍然可以进行完全相同的比较。

比较有两种潜在的定义,显然会给出不同的答案:

comparison==算法中的所有比较操作

在这种情况下,会发生以下比较:

  1. 我达到最后一个范围了吗
  2. 我达到最后一个范围了吗
  3. 是range2-elem<range1 elem
  4. 是range2 elem>range1 elem

在简单的情况下,N1==N2==1,这可以生成至少6个比较(例如,1、2、3、4、1、2:其中range1={1}和range2={10}),这远远超过了任一算法所允许的范围。所以不可能是这样。

比较==检查elem1和elem2是否相等

在这种情况下,对范围1的每个元素都有两次比较,直到它找到范围2的所有元素,或者它到达范围1的末端,在那里它停止(在发现它已经到达范围1末端时)。

因此,据我所知,复杂性与N2的长度无关,复杂性应该是

2*(N1)

注意,对于";"比较";,2*(N1+N2-1)似乎只在N2==1时成立,而2*(N1+N2)-1从不成立,因为在非最大复杂度的情况下比较的数量只是奇数(范围2的数字不在范围1内且不大于最大值(范围1))。

任何其他的比较定义都是有选择性的。我唯一能想到的另一件事是,编译器优化了某些步骤,比如当元素没有增加时,不检查它是否再次到达范围2的末尾(这也会使算法根据需要依赖于N2),但我看不出还有什么可以优化的,以便将数字降到与上述两种复杂性完全匹配的程度。

还有谁能得到更好的答案?我现在和OP一样对此感到好奇。

首先,它必须进行两次比较来检查等价性,定义为:

 if (!(a<b) && !(b<a))

if (!comp(a,b) && !comp(b,a))

那么它必须将每个可能的范围的整体相互对照减去1。

关键在这一行

两个元素a和b被认为是等价的if!(a<b)&amp!(b<a)或if!comp(a,b)&amp!comp(b,a)

让我们以小于谓词<排序的集合

[2,3]
[1,2,3,4]

比较元素2和1:2<1返回false,因此它们可以是等效元素,或者2可以大于1。如果它们是等价的,则1<2也会返回false,但不会。因此,对于第二集合丢弃1,并且接下来考虑第二集合的值2。

最大比较数:2*(M+N)-1。该算法在O(N+M)中运行。