定义于头文件
算法库提供大量用途的函数(例如查找、排序、计数、操作),它们在元素范围上操作。注意范围定义为 [first, last)
,其中 last
指代要查询或修改的最后元素的后一个元素。
std::partition
template< class BidirIt, class UnaryPredicate > | (1) | (C++11 前) |
template< class ForwardIt, class UnaryPredicate > | (C++11 起) (C++20 前) | |
template< class ForwardIt, class UnaryPredicate > | (C++20 起) | |
template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate > ForwardIt partition( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, UnaryPredicate p ); | (2) | (C++17 起) |
1) 重排序范围 [first, last)
中的元素,使得谓词 p
对其返回 true 的元素前于谓词 p
对其返回 false 的元素。不保持相对顺序。
2) 同 (1) ,但按照 policy
执行。此重载仅若 std::is_execution_policy_v
first, last | - | 要重排序的元素范围 |
policy | - | 所用的执行策略。细节见执行策略。 |
p | - | 若元素应在顺序中先于其他元素则返回 true 的一元谓词。 对每个(可为 const 的) |
类型要求 | ||
- BidirIt 必须满足遗留双向迭代器 (LegacyBidirectionalIterator) 的要求。 | ||
- ForwardIt 必须满足值可交换 (ValueSwappable) 和 遗留向前迭代器 (LegacyForwardIterator) 的要求。然而,若 ForwardIt 亦满足 遗留双向迭代器 (LegacyBidirectionalIterator) 的要求则操作更高效 | ||
- UnaryPredicate 必须满足谓词 (Predicate) 的要求。 |
指向第二组元素首元素的迭代器。
给定 N = std::distance(first,last) ,
1) 准确 N 次应用谓词。若 ForwardIt
满足遗留双向迭代器 (LegacyBidirectionalIterator) 的要求则至多交换 N/2 次,否则至多交换 N 次。
2) O(N log N)
次交换, and O(N)
次应用谓词。
拥有名为 ExecutionPolicy
的模板形参的重载按下列方式报告错误:
ExecutionPolicy
为标准策略之一,则调用 std::terminate 。对于任何其他 ExecutionPolicy
,行为是实现定义的。- template<class ForwardIt, class UnaryPredicate>
- ForwardIt partition(ForwardIt first, ForwardIt last, UnaryPredicate p)
- {
- first = std::find_if_not(first, last, p);
- if (first == last) return first;
-
- for (ForwardIt i = std::next(first); i != last; ++i) {
- if (p(*i)) {
- std::iter_swap(i, first);
- ++first;
- }
- }
- return first;
- }
- #include <iostream>
- #include <algorithm>
- #include <functional>
- #include <vector>
- #include <iterator>
-
- using namespace std;
-
- struct Cell
- {
- int x;
- int y;
-
- Cell &operator +=(const Cell &cell)
- {
- x += cell.x;
- y += cell.y;
- return *this;
- }
-
- bool operator <(const Cell &cell) const
- {
- if (x == cell.x)
- {
- return y < cell.y;
- }
- else
- {
- return x < cell.x;
- }
- }
- };
-
- std::ostream &operator<<(std::ostream &os, const Cell &cell)
- {
- os << "{" << cell.x << "," << cell.y << "}";
- return os;
- }
-
- template <class ForwardIt>
- void quicksort(ForwardIt first, ForwardIt last)
- {
- if (first == last)
- {
- return ;
- }
-
- auto pivot = *std::next(first, std::distance(first, last) / 2);
- auto func1 = [pivot](const decltype(pivot) & em)
- {
- return em < pivot;
- };
-
- ForwardIt middle1 = std::partition(first, last, func1);
-
- auto func2 = [pivot](const decltype(pivot) & em)
- {
- return !(pivot < em);
- };
-
- ForwardIt middle2 = std::partition(middle1, last, func2);
- quicksort(first, middle1);
- quicksort(middle2, last);
- return;
- }
-
- int main()
- {
- std::cout.setf(std::ios_base::boolalpha);
-
- auto func1 = [](Cell & cell, const Cell & t)
- {
- cell += t;
- return cell;
- };
-
- Cell cell{99, 100};
- Cell t{2, 3};
- auto func2 = std::bind(func1, cell, t);
-
- vector<Cell> cells(8);
- std::generate(cells.begin(), cells.end(), func2);
- std::cout << "cells : ";
- std::copy(cells.begin(), cells.end(), std::ostream_iterator<Cell>(std::cout, " "));
- std::cout << std::endl;
-
- auto is_even = [](const Cell & cell)
- {
- return cell.x % 2 == 1 && cell.y % 2 == 1;
- };
- std::cout << "is_partitioned: " << std::is_partitioned(cells.begin(), cells.end(), is_even);
- std::cout << std::endl << std::endl;
-
- std::partition(cells.begin(), cells.end(), is_even);
- std::cout << "cells : ";
- std::copy(cells.begin(), cells.end(), std::ostream_iterator<Cell>(std::cout, " "));
- std::cout << std::endl;
- std::cout << "is_partitioned: " << std::is_partitioned(cells.begin(), cells.end(), is_even);
- std::cout << std::endl << std::endl;
-
- std::reverse(cells.begin(), cells.end());
- std::cout << "cells : ";
- std::copy(cells.begin(), cells.end(), std::ostream_iterator<Cell>(std::cout, " "));
- std::cout << std::endl;
- std::cout << "is_partitioned: " << std::is_partitioned(cells.begin(), cells.end(), is_even);
- std::cout << std::endl << std::endl;
-
- quicksort(std::begin(cells), std::end(cells));
- std::cout << "Sorted using quicksort: ";
- std::copy(cells.begin(), cells.end(), std::ostream_iterator<Cell>(std::cout, " "));
- std::cout << std::endl;
- return 0;
- }