今天继续。

C++11新增的关于Non-modifying sequence operations和Modifying sequence operations的算法已经写了。具体信息见之前的博客。

以下開始C++11新增的关于Partitions的算法:

Partitions:即分区的意思。

非常多人可能还不熟悉partition,所以先说一说partition算法。须要说明的是这不是C++11新增的内容。

但为了更方便大家理解,还是先写一写std::partition。

std::partition

原型:

template <class ForwardIterator, class UnaryPredicate>
ForwardIterator partition (ForwardIterator first,
ForwardIterator last, UnaryPredicate pred);

作用:

Rearranges the elements from the range [first,last), in such a way that all the elements for which pred returns true precede all those for which it returns false. The iterator returned points to the first element of the second group.

须要注意一下返回值:

An iterator that points to the first element of the second group of elements (those for which pred returns false), or last if this group is empty

返回的迭代器是指向第二个区间的第一个元素!!!

应用:

#include <iostream>     // std::cout
#include <algorithm> // std::partition
#include <vector> // std::vector bool IsOdd(int i) { return (i % 2) == 1; } int main() {
std::vector<int> myvector; // set some values:
for (int i = 1; i<10; ++i)
myvector.push_back(i); // 1 2 3 4 5 6 7 8 9 std::vector<int>::iterator bound;
bound = std::partition(myvector.begin(), myvector.end(), IsOdd); // print out content:
std::cout << "odd elements:";
for (std::vector<int>::iterator it = myvector.begin(); it != bound; ++it)
std::cout << ' ' << *it;
std::cout << '\n'; std::cout << "even elements:";
for (std::vector<int>::iterator it = bound; it != myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n'; std::cout << "Now myvector is: ";
for (auto it = myvector.begin(); it != myvector.end(); it++)
{
std::cout << ' ' << *it;
}
std::cout << std::endl; return 0;
}
//输出:
//odd elements : 1 9 3 7 5
//even elements : 6 4 8 2
//Now myvector is : 1 9 3 7 5 6 4 8 2

我们是想依照奇数偶数进行分组。目的达到了。可是还不够完美。由于每一个分区部分的元素与之前相比,相对位置变化了。

这个时候,就须要更稳定的算法了。直接上代码了。执行结果对照的非常明显:

stable_partition

#include <iostream>     // std::cout
#include <algorithm> // std::partition
#include <vector> // std::vector bool IsOdd(int i) { return (i % 2) == 1; } int main() {
std::vector<int> myvector; // set some values:
for (int i = 1; i<10; ++i)
myvector.push_back(i); // 1 2 3 4 5 6 7 8 9 std::vector<int>::iterator bound;
bound = std::partition(myvector.begin(), myvector.end(), IsOdd); // print out content:
std::cout << "odd elements:";
for (std::vector<int>::iterator it = myvector.begin(); it != bound; ++it)
std::cout << ' ' << *it;
std::cout << '\n'; std::cout << "even elements:";
for (std::vector<int>::iterator it = bound; it != myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n'; std::cout << "Now myvector is: ";
for (auto it = myvector.begin(); it != myvector.end(); it++)
{
std::cout << ' ' << *it;
}
std::cout << std::endl; std::cout << "Now let us " << std::endl;
std::vector<int> myvector2; // set some values:
for (int i = 1; i<10; ++i)
myvector2.push_back(i); // 1 2 3 4 5 6 7 8 9 std::vector<int>::iterator bound2;
bound2 = std::stable_partition(myvector2.begin(), myvector2.end(), IsOdd); // print out content:
std::cout << "odd elements:";
for (std::vector<int>::iterator it = myvector2.begin(); it != bound2; ++it)
std::cout << ' ' << *it;
std::cout << '\n'; std::cout << "even elements:";
for (std::vector<int>::iterator it = bound2; it != myvector2.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n'; std::cout << "Now myvector is: ";
for (auto it = myvector2.begin(); it != myvector2.end(); it++)
{
std::cout << ' ' << *it;
}
std::cout << std::endl; return 0;
}
//输出:
//odd elements : 1 9 3 7 5
//even elements : 6 4 8 2
//Now myvector is : 1 9 3 7 5 6 4 8 2
//Now let us
//odd elements : 1 3 5 7 9
//even elements : 2 4 6 8
//Now myvector is : 1 3 5 7 9 2 4 6 8

如今開始介绍C++11新增的。

is_partitioned

原型:

template <class InputIterator, class UnaryPredicate>
bool is_partitioned (InputIterator first, InputIterator last, UnaryPredicate pred);

作用:

Test whether range is partitioned

Returns true if all the elements in the range [first,last) for which pred returns true precede those for which it returns false.

应用:

#include <iostream>     // std::cout
#include <algorithm> // std::partition
#include <vector> // std::vector bool IsOdd(int i) { return (i % 2) == 1; } int main() {
std::vector<int> myvector; // set some values:
for (int i = 1; i<10; ++i)
myvector.push_back(i); // 1 2 3 4 5 6 7 8 9 std::vector<int>::iterator bound;
bound = std::partition(myvector.begin(), myvector.end(), IsOdd); // print out content:
std::cout << "odd elements:";
for (std::vector<int>::iterator it = myvector.begin(); it != bound; ++it)
std::cout << ' ' << *it;
std::cout << '\n'; std::cout << "even elements:";
for (std::vector<int>::iterator it = bound; it != myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n'; std::cout << "Now myvector is: ";
for (auto it = myvector.begin(); it != myvector.end(); it++)
{
std::cout << ' ' << *it;
}
std::cout << std::endl; std::cout << "Now let us use stable_partition:" << std::endl;
std::vector<int> myvector2; // set some values:
for (int i = 1; i<10; ++i)
myvector2.push_back(i); // 1 2 3 4 5 6 7 8 9 std::vector<int>::iterator bound2;
bound2 = std::stable_partition(myvector2.begin(), myvector2.end(), IsOdd); // print out content:
std::cout << "odd elements:";
for (std::vector<int>::iterator it = myvector2.begin(); it != bound2; ++it)
std::cout << ' ' << *it;
std::cout << '\n'; std::cout << "even elements:";
for (std::vector<int>::iterator it = bound2; it != myvector2.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n'; std::cout << "Now myvector is: ";
for (auto it = myvector2.begin(); it != myvector2.end(); it++)
{
std::cout << ' ' << *it;
}
std::cout << std::endl; std::cout << "Now, let us use is_partitioned on myvector2:" << std::endl;
if (std::is_partitioned(myvector2.begin(), myvector2.end(), IsOdd))
std::cout << " (partitioned)\n";
else
std::cout << " (not partitioned)\n"; std::cout << "Now, let us use is_partitioned on en empty vector:" << std::endl;
std::vector<int> myvector3;
if (std::is_partitioned(myvector3.begin(), myvector3.end(), IsOdd))
std::cout << " (partitioned)\n";
else
std::cout << " (not partitioned)\n"; return 0;
}
//输出:
odd elements : 1 9 3 7 5
even elements : 6 4 8 2
Now myvector is : 1 9 3 7 5 6 4 8 2
Now let us use stable_partition :
odd elements : 1 3 5 7 9
even elements : 2 4 6 8
Now myvector is : 1 3 5 7 9 2 4 6 8
Now, let us use is_partitioned on myvector2 :
(partitioned)
Now, let us use is_partitioned on en empty vector :
(partitioned)

从输出结果看,我们须要明白:

If the range is empty, the function returns true.

上面的几个算法,无论怎样折腾,都是在一个vector进行的,结果也还是在一个vector中,于是C++11新增了这个:

partition_copy

原型:

template <class InputIterator, class OutputIterator1,
class OutputIterator2, class UnaryPredicate pred>
pair<OutputIterator1,OutputIterator2>
partition_copy (InputIterator first, InputIterator last,
OutputIterator1 result_true, OutputIterator2 result_false,
UnaryPredicate pred);

作用:

Copies the elements in the range [first,last) for which pred returns true into the range pointed by result_true, and those for which it does not into the range pointed by result_false.

应用:

#include <iostream>     // std::cout
#include <algorithm> // std::partition_copy, std::count_if
#include <vector> // std::vector bool IsOdd(int i) { return (i % 2) == 1; } int main() {
std::vector<int> foo{ 1,2,3,4,5,6,7,8,9 };
std::vector<int> odd, even; // resize vectors to proper size:
unsigned n = std::count_if(foo.begin(), foo.end(), IsOdd);
odd.resize(n); even.resize(foo.size() - n); // partition:
std::partition_copy(foo.begin(), foo.end(), odd.begin(), even.begin(), IsOdd); // print contents:
std::cout << "odd: "; for (int& x : odd) std::cout << ' ' << x; std::cout << '\n';
std::cout << "even: "; for (int& x : even) std::cout << ' ' << x; std::cout << '\n'; return 0;
}
//输出:
//odd: 1 3 5 7 9
//even : 2 4 6 8

接下来剩最后一个:

partition_point

从算法名字就能略知一二。于是直接上代码演示样例:

#include <iostream>     // std::cout
#include <algorithm> // std::partition, std::partition_point
#include <vector> // std::vector bool IsOdd(int i) { return (i % 2) == 1; } int main() {
std::vector<int> foo{ 1,2,3,4,5,6,7,8,9 };
std::vector<int> foo2{ 1,2,3,4,5,6,7,8,9 };
std::vector<int> odd;
std::vector<int> odd2; std::partition(foo.begin(), foo.end(), IsOdd); auto it = std::partition_point(foo.begin(), foo.end(), IsOdd);
odd.assign(foo.begin(), it); auto bound = std::partition(foo2.begin(), foo2.end(), IsOdd);
for (std::vector<int>::iterator it = foo2.begin(); it != bound; ++it)
odd2.push_back(*it);
//odd2.assign(foo.begin(), bound); // print contents of odd:
std::cout << "odd:";
for (int& x : odd) std::cout << ' ' << x;
std::cout << '\n'; std::cout << "odd2:";
for (int& x : odd2) std::cout << ' ' << x;
std::cout << '\n'; return 0;
}

因此:

partition_point

Returns an iterator to the first element in the partitioned range [first,last) for which pred is not true, indicating its partition point.

个人认为这个算法用处不大。

个人认为主要应用于已经partition的range上还算有优势!

最新文章

  1. Sql Server函数全解&lt;三&gt;数据类型转换函数和文本图像函数
  2. apple常用网址
  3. 登陆数据库,界面一直保持正在登陆的状态,oracle使用界面无法登陆
  4. Intellij IDEA 自动生成 serialVersionUID
  5. How to create/restore a slave using GTID replication in MySQL 5.6
  6. fzu1342
  7. NOIP2014飞扬的小鸟[DP][WRONG]
  8. UITabBarController 微信
  9. 信与信封问题(codevs 1222)
  10. c# 绘图常用对象和方法
  11. 第12届北师大校赛热身赛第二场 A.不和谐的长难句1
  12. 测试框架mochajs详解
  13. Boost库学习之旅入门篇
  14. fragment嵌套,viewpager嵌套 不能正确显示
  15. 南阳OJ-14-会场安排问题---区间不相交
  16. saltstack主机管理项目:计主机管理项目命令分发器(三)
  17. db2 执行报错收集
  18. oracle导出大数据
  19. Hunter’s Apprentice 【判断多边形边界曲线顺逆时针】
  20. 微信小程序裁剪图片成圆形

热门文章

  1. SqlHelper——仅仅由于在人群中多看了你一眼
  2. HDU1237 简单计算器 【栈】+【逆波兰式】
  3. oracle 11gR2 如何修改scan vip 地址 /etc/hosts方式
  4. [AHOI 2009] 同类分布
  5. ITWorld:2014年全球最杰出的14位编程天才
  6. extjs 与html相结合 自定义
  7. 看似简单!解读C#程序员最易犯的7大错误
  8. 通过obs进行推流
  9. mock non-virtual methods
  10. Caffe Batch Normalization推导