今天继续。

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上还算有优势!

C++11新特性应用--介绍几个新增的便利算法(用于分区的几个算法)的更多相关文章

  1. C++11新特性应用--介绍几个新增的便利算法(不更改容器中元素顺序的算法)

    总所周知.C++ STL中有个头文件,名为algorithm.即算法的意思. The header<algorithm>defines a collection of functions ...

  2. C++11新特性应用--介绍几个新增的便利算法(用于排序的几个算法)

    继续C++11在头文件algorithm中添加的算法. 至少我认为,在stl的算法中,用到最多的就是sort了,我们不去探索sort的源代码.就是介绍C++11新增的几个关于排序的函数. 对于一个序列 ...

  3. Java 11 新特性介绍

    Java 11 已于 2018 年 9 月 25 日正式发布,之前在Java 10 新特性介绍中介绍过,为了加快的版本迭代.跟进社区反馈,Java 的版本发布周期调整为每六个月一次——即每半年发布一个 ...

  4. C++11新特性总结 (二)

    1. 范围for语句 C++11 引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素 vector<int> vec = {1,2,3,4,5,6}; ...

  5. [转载] C++11新特性

    C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...

  6. C++11 新特性之智能指针(shared_ptr, unique_ptr, weak_ptr)

    这是C++11新特性介绍的第五部分,涉及到智能指针的相关内容(shared_ptr, unique_ptr, weak_ptr). shared_ptr shared_ptr 基本用法 shared_ ...

  7. 【C++11新特性】 C++11智能指针之weak_ptr

    如题,我们今天要讲的是C++11引入的三种智能指针中的最后一个:weak_ptr.在学习weak_ptr之前最好对shared_ptr有所了解.如果你还不知道shared_ptr是何物,可以看看我的另 ...

  8. Redis 6.0 新特性 ACL 介绍

    Redis 6.0 新特性 ACL 介绍 Intro 在 Redis 6.0 中引入了 ACL(Access Control List) 的支持,在此前的版本中 Redis 中是没有用户的概念的,其实 ...

  9. c++ 11 线程池---完全使用c++ 11新特性

    前言: 目前网上的c++线程池资源多是使用老版本或者使用系统接口实现,使用c++ 11新特性的不多,最近研究了一下,实现一个简单版本,可实现任意任意参数函数的调用以及获得返回值. 0 前置知识 首先介 ...

随机推荐

  1. 使用Swift和SpriteKit写一个忍者游戏

    这篇文章的游戏使用SpriteKit和Swift语言来完毕. SpriteKit是苹果自己的游戏引擎,更能贴合iOS系统底层的API,只是架构和实现上都是模仿了Cocos2D.所以使用上事实上区别不大 ...

  2. [Oracle] - Connect to a PDB of Oracle12c

    Story about CDB and PDB Oracle12c has a new feature and definition of CDB and PDB. If you first use ...

  3. 源码高速定位工具-qwandry

    https://github.com/adamsanderson/qwandry qwandry 能高速定位到我们须要找到 库文件, 项目 的工具. Ruby中实现高速定位的方法有好多种.我知道的有三 ...

  4. Rails中关联数据表的添加操作(嵌套表单)

    很早就听说有Web敏捷开发这回事,最近终于闲了下来,可以利用业余的时间学些新东西,入眼的第一个东东自然是Ruby on Rails.Rails中的核心要素也就是MVC.ORM这些了,因此关于Rails ...

  5. oracle 11gR2 如何修改public ip

    修改public ip 修改前后ip信息 修改前ip信息 p570a 192.168.1.10 p570b 192.168.1.11 修改后ip信息 p570a 1.7.3.112 p570a 1.7 ...

  6. netty可靠性

    Netty的可靠性 首先,我们要从Netty的主要用途来分析它的可靠性,Netty目前的主流用法有三种: 1) 构建RPC调用的基础通信组件,提供跨节点的远程服务调用能力: 2) NIO通信框架,用于 ...

  7. caffe mnist实例 --lenet_train_test.prototxt 网络配置详解

    1.mnist实例 ##1.数据下载 获得mnist的数据包,在caffe根目录下执行./data/mnist/get_mnist.sh脚本. get_mnist.sh脚本先下载样本库并进行解压缩,得 ...

  8. Web Api和Asp.Net mvc post请求区别

    这是mvc的,mvc的post请求可以这样写参数,但是web api的不行.而且content_type:"application/json" 必须要写 下面这是web api的: ...

  9. 关于flex布局中的兼容性问题

    这几天在做项目中用到了flex布局,但是在测试的过程中发现他的兼容性实在是太差了,仅仅用到水平和垂直居中的样式,没想到兼容性代码就写了好几行. display:flex; display:-webki ...

  10. LeetCode Golang 8. 字符串转换整数 (atoi)

    8. 字符串转换整数 (atoi) 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组 ...