在阅读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,哪个站点是正确的,并且任何人都可以解释如何计算这个最大数量或比较,即:
答案 0 :(得分:5)
警告:在阅读该帖子的每个人都意识到他们不知道他们在谈论什么(包括我)之前,已经添加了这个答案的声誉。如果在将来的某个时候有一个接受的答案,并不反对该算法的所有文档,请多加注意!
2 *(无论如何)位很容易解释,我在下面这样做了。 (无论如何)这一点让我感到非常困惑,据我所知,它应该是
2*(count1)
并且与第二范围的长度完全无关。要么我错过了某些东西(最有可能),要么文档错了(不会那么好......)。
如果您需要我的推理,请参阅下文。如果我错了并且有人得到了正确的答案,请告诉我,以便我可以删除这篇文章!
如果你问为什么它 2 次(count1 + count2)-1,那么关键就在这一行:
使用运算符<来比较元素。对于第一个版本,和comp为第二个版本。如果(!(a
每次比较两个元素时,它会进行两次比较:我不等于它,它不等于我。
它必须做的这些“比较对”的 MAXIMUM 数量是非常难以确定的。事实上,我无法弄明白。据我所知,它应该与第二范围的长度无关......
我已经看了好几天,并根据cppreference中的代码示例做了一些测试,老实说我不知道这是怎么回事。
算法意味着OP挖出的源代码表示range2必须是range1的子集,并且两者都是有序的,所以没有必要检查一个元素两次。这意味着算法必须最多检查range1的所有元素,另外还要检查range2的元素是否大于range1中的任何元素。不仅如此,但是在range2中有2或20个元素的位置并不重要,它仍然可以进行完全相同的比较。
有两种可能的比较定义,显然会给出不同的答案:
在这种情况下,会发生以下比较:
在简单情况下N1 == N2 == 1,这可以产生至少6个比较(1,2,3,4,1,2:其中range1 = {1}和range2 = {10},例如),这远远超过任何算法允许。所以情况并非如此。
在这种情况下,range1的每个元素都有两个比较,直到它找到了range2的所有元素,或者它到达range1的末尾,它停止了(一旦发现它已经到达range1的末尾)。 / p>
因此,据我所知,复杂性与N2的长度无关,复杂性应该是
2*(N1)
注意,对于“比较”的这个定义,2 *(N1 + N2 - 1)仅对N2 == 1持有,而2 *(N1 + N2)-1从不成为比较次数在非最大复杂情况下只是奇数(range2的数字不在range1且不大于max(range1))。
任何其他比较定义都是有选择性的。我能想到的唯一另一件事是编译器优化了某些步骤,比如当元素没有递增时不检查它是否再次到达range2的末尾(这也会使算法依赖于N2),但是我无法看到其他任何可以优化的内容,以便将数字降低到完全符合所述复杂性的内容。
......其他人得到了更好的答案吗?我现在和OP一样好奇。
答案 1 :(得分:0)
首先,它必须进行2次比较以检查等效性,定义为:
if (!(a<b) && !(b<a))
或
if (!comp(a,b) && !comp(b,a))
然后它必须检查每个可能的范围相互之间减去1。
答案 2 :(得分:0)
关键在这一行
如果!(a&lt; b)&amp;&amp; !(b&lt; a)或if!comp(a,b)&amp;&amp; !排版(B,A)
让我们举个例如 less-than 谓词&lt; 和已排序集
[2,3]
[1,2,3,4]
比较元素2和1:2&lt; 1返回false,因此它们可以是等效元素,或者2可以大于1.如果它们是等价的,则1&lt; 1。 2也将返回false,但事实并非如此。因此,第二组丢弃1,接下来考虑第二组的值2.
最大比较:2 *(M + N)-1。 该算法在O(N + M)中运行。