![](/img/trans.png)
[英]What is the time complexity of judging if two vectors are equal in C++?
[英]C++ sort vectors time complexity
假设我有一个带有N个向量的vector<vector<int>> L
,并且所有向量上的int
s总数之和最多为M。标准C ++排序sort(L.begin(), L.end())
吗?
vector<int>
比较函数的运行时间最多为O(M),因此一个明显的界限是O(NM log N)。 但是,如果我们执行标准的mergesort,我们可以看到在每个O(log N)级别中最多完成了O(M)整数比较,因此运行时为O((N + M)log N)。 这是因为比较长度为A和B的两个向量需要O(min(A,B))时间。
C ++标准是否保证运行时为O((N + M)log N)?
没有足够的信息。 您还需要知道N
向量上M
值的分布 。 有了这些,就可以直接找到整体复杂性:
std::sort
具有O(N·log(N))
比较的复杂度。
std::vector
使用std::lexicographical_compare(v1, v2)
进行比较,比较复杂度为O(min(v1.size(), v2.size()))
比较。
int
比较的复杂度为O(1)
。
我们会通知E(M, N)
是在一个功能M
, N
返回每一对内向量之间的最小元件的平均数 。
M/N
Big Oh = N·log(N)·E(M, N)·1
。
M·log(N)
。 您可以使用离散概率分布理论来计算E(M, N)
函数对于M
在N
任何分布的意义。
编辑1 :要弄清楚这种情况的重要性:考虑一个总是使我的向量看起来像的分布:
outer[0].size() == 1,
outer[1].size() == 1,
outer[2].size() == 1,
...,
outer[M-1].size() == (M - N + 1)
在这种情况下, E(M, N) = 1
,因为std::lexicographical_compare
只会有一个其他元素要与任何一对元素进行比较。 因此,对于这种特定的分布,我将始终具有O(N·log(N))
的复杂度。 但是如果分布均匀,我将得到O(M·log(N))
。
编辑2 :在定义分布的注释之后,让我们尝试找到E(M, N)
。
首先,请注意总共有T = (N choose 2) = N(N - 1)(1/2)
向量比较的不同组合。
一个(只有一个)组合将进行X = O((M - N + 2)(1/2))
比较,并且发生概率P(X) = 1/T
其他所有组合仅需要1
比较( O(1)
),因此这些情况的发生概率为P(1) = (T - 1)/T
求平均值很简单: X·P(X) + 1·P(1)
。
鉴于此, WolframAlpha说: E(M, N) = (M + (N - 2) N)/((N - 1) N)
。
该函数乘以N log(N)
得到(M + (N - 2) N) log(N) / (N - 1)
,可以进一步简化为您要查找的Big Oh: O((M/N + N) log(N))
。
如果您的Integers 或多或少是随机的 1) ,大多数比较只需要比较每个向量的前几个整数(直到第一个不匹配),所以实际上/平均
M(反常)对算法复杂度没有任何影响
给你一些想法:即使向量有无限长并且最频繁出现的整数的p
概率为50%, 平均您也需要进行少于2次比较 :
k < ∑ i*p^i = p/(1-p)^2 | p=0.5
k < ∑ i*0.5^i = 2;
对于其他概率,结果为:
60% -> k < 2.5
70% -> k < 3.4
80% -> k < 5.0
90% -> k < 10.0
请记住,所有这些数字都是整数比较的平均数的 上限 ,并且与向量中的元素数无关
1)随机是指密码意义上的随机。 这些数字甚至不必通过大多数随机数字质量测试。 唯一的要求是它们不能以系统的方式形成相同的前缀(随向量的长度而增长)。
除了恶意输入,我目前无法想到一个不符合“或多或少随机性”的现实示例,但可能还有其他情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.