C++11标准模板(STL)- 算法(std::partition_copy)
创始人
2024-01-25 03:27:41
0
定义于头文件 

算法库提供大量用途的函数(例如查找、排序、计数、操作),它们在元素范围上操作。注意范围定义为 [first, last) ,其中 last 指代要查询或修改的最后元素的后一个元素。

复制一个范围,将各元素分为两组

std::partition_copy
template< class InputIt, class OutputIt1,

          class OutputIt2, class UnaryPredicate >
std::pair
     partition_copy( InputIt first, InputIt last,
                     OutputIt1 d_first_true, OutputIt2 d_first_false,

                     UnaryPredicate p );
(1)(C++11 起)
(C++20 前)
template< class InputIt, class OutputIt1,

           class OutputIt2, class UnaryPredicate >
constexpr std::pair
               partition_copy( InputIt first, InputIt last,
                               OutputIt1 d_first_true, OutputIt2 d_first_false,

                               UnaryPredicate p );
(C++20 起)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,

          class ForwardIt3, class UnaryPredicate >
std::pair
     partition_copy( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
                     ForwardIt2 d_first_true, ForwardIt3 d_first_false,

                     UnaryPredicate p );
(2)(C++17 起)

1) 从范围 [first, last) 复制元素到二个不同范围,取决于谓词 p 的返回值。复制满足谓词 p 的元素到始于 d_first_true 的范围。复制剩余元素到始于 d_first_false 的范围。

若输入范围与任一输出范围重叠,则行为未定义。

2) 同 (1) ,但按照 policy 执行。此重载仅若 std::is_execution_policy_v> 为 true 才参与重载决议。

参数

first, last-要排序的元素范围
d_first_true-满足 p 的元素的输出范围起始
d_first_false-不满足 p 的元素的输出范围起始
policy-所用的执行策略。细节见执行策略。
p-若元素应置于 d_first_true 中则返回 ​true 的一元谓词。

对每个(可为 const 的) VT 类型参数 v ,其中 VTInputIt 的值类型,表达式 p(v) 必须可转换为 bool ,无关乎值类别,而且必须不修改 v 。从而不允许 VT& 类型参数,亦不允许 VT ,除非对 VT 而言移动等价于复制 (C++11 起)。 ​

类型要求
- InputIt 必须满足遗留输入迭代器 (LegacyInputIterator) 的要求。
- 解引用 InputIt 结果的类型必须满足可复制赋值 (CopyAssignable) 的要求。
- OutputIt1, OutputIt2 必须满足遗留输出迭代器 (LegacyOutputIterator) 的要求。
- ForwardIt1, ForwardIt2, ForwardIt3 必须满足遗留向前迭代器 (LegacyForwardIterator) 的要求。ForwardIt1 的值类型必须为可复制赋值 (CopyAssignable) ,可写入到 ForwardIt2 和 ForwardIt3 ,并且可转换为 UnaryPredicate 的参数类型
- UnaryPredicate 必须满足谓词 (Predicate) 的要求。

返回值

从指向 d_first_true 范围结尾的迭代器和指向 d_first_false 范围结尾的迭代器构造的 std::pair 。

复杂度

准确应用 distance(first, last)p

对于带 ExecutionPolicy 的重载,若 ForwardIt 的值类型非可复制构造 (CopyConstructible) ,则可能有性能开销。

异常

拥有名为 ExecutionPolicy 的模板形参的重载按下列方式报告错误:

  • 若作为算法一部分调用的函数的执行抛出异常,且 ExecutionPolicy 为标准策略之一,则调用 std::terminate 。对于任何其他 ExecutionPolicy ,行为是实现定义的。
  • 若算法无法分配内存,则抛出 std::bad_alloc 。

 

可能的实现

template
std::pairpartition_copy(InputIt first, InputIt last,OutputIt1 d_first_true, OutputIt2 d_first_false,UnaryPredicate p)
{while (first != last) {if (p(*first)) {*d_first_true = *first;++d_first_true;} else {*d_first_false = *first;++d_first_false;}++first;}return std::pair(d_first_true, d_first_false);
}

调用示例

#include 
#include 
#include 
#include 
#include 
#include 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;
}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 vCells(8);std::generate(vCells.begin(), vCells.end(), func2);std::cout << "vCells :              ";std::copy(vCells.begin(), vCells.end(), std::ostream_iterator(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(vCells.begin(), vCells.end(), is_even);std::cout << std::endl << std::endl;std::list lCells(vCells.size());auto vIt = std::partition_copy(vCells.begin(), vCells.end(), lCells.begin(), lCells.end(), is_even);std::cout << "lCells :              ";std::copy(lCells.begin(), lCells.end(), std::ostream_iterator(std::cout, " "));std::cout << std::endl;std::cout << "is_partitioned:       " << std::is_partitioned(vIt.first, vIt.second, is_even);std::cout << std::endl << std::endl;std::reverse(vCells.begin(), vCells.end());std::cout << "vCells :              ";std::copy(vCells.begin(), vCells.end(), std::ostream_iterator(std::cout, " "));std::cout << std::endl;std::cout << "is_partitioned:       " << std::is_partitioned(vCells.begin(), vCells.end(), is_even);std::cout << std::endl << std::endl;vIt = std::partition_copy(vCells.begin(), vCells.end(), lCells.begin(), lCells.end(), is_even);std::cout << "lCells :              ";std::copy(lCells.begin(), lCells.end(), std::ostream_iterator(std::cout, " "));std::cout << std::endl;std::cout << "is_partitioned:       " << std::is_partitioned(vIt.first, vIt.second, is_even);std::cout << std::endl << std::endl;return 0;
}

输出

 

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...