![](/img/trans.png)
[英]use std::stable_partition and ::iterator with a vector
[英]What is the difference between std::stable_partition() and std::partition()?
stable_partition(vect.begin(), vect.end(), [](int x) { return x % 2 == 0; });
partition(vect.begin(), vect.end(), [](int x) {
return x % 2 == 0;
});
上面的代码是为了解释两者之间的区别。
“稳定”意味着等效元素的顺序不会改变:
来自cppreference.com 的std::stable_partition
:
重新排序范围 [first, last) 中的元素,使得谓词
p
为其返回true
所有元素位于谓词p
为其返回false
的元素之前。 元素的相对顺序被保留。
解决这个问题的最好方法可能是举个例子。 让我在这里抄袭cppreference 中的示例:
#include <iostream>
#include <algorithm>
#include <vector>
int main()
{
std::vector<int> v{0, 0, 3, 0, 2, 4, 5, 0, 7};
std::stable_partition(v.begin(), v.end(), [](int n){return n>0;});
for (int n : v) {
std::cout << n << ' ';
}
std::cout << '\n';
}
运行这个会得到: 3 2 4 5 7 0 0 0 0
。 3, 2, 4, 5, 7 等价于由> 0
谓词定义的关系,并且正如预期的那样,它们没有重新排序。
但是,如果将stable_partition
替换为同一示例的partition
,则会得到: 7 5 3 4 2 0 0 0 0
。 这次不能保证保持等效元素的顺序,显然它不是。
如其他答案中所述, std::stable_partition
保留谓词为其返回true
和false
的组中元素的相对顺序。
但这需要付出代价: std::stable_partition
具有更高的时间/空间复杂度。 如果可以分配额外的存储空间,则可以在O(n)
时间内实现std::stable_partition
。 然而,就地稳定分区不能在O(n)
时间内实现。 它可以在O(n log n)
时间内完成。 可以在此处找到一个简单的分而治之算法的示例。
std::stable_partition
C++ 参考读取:
复杂性(
std::stable_partition
)给定
N = last - first
,如果有足够的额外内存,正好
N
应用谓词和O(N)
交换。 如果内存不足,最多N log N
交换。
还要注意std::stable_partition
需要双向迭代器,而std::partition
可以对前向迭代器进行操作。 但是,在双向迭代器上效率更高:
复杂性(
std::partition
)鉴于
N = std::distance(first,last)
,谓词的
N
应用。 至多N/2
互换如果ForwardIt
满足的要求LegacyBidirectionalIterator
,和至多N
互换否则。
如果分区后元素的相对顺序不重要,请使用std::partition
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.