C++ partition_point()函数(详解版)
事实上,有些数据本身就已经是按照某个筛选规则分好组的,例如:
类似上面这样已经“分好组”的数据,在使用时会有一个问题,即不知道两组数据之间的分界在什么位置。有读者可能想到,再调用一次 partition()、stale_partition() 或者 partition_copy() 不就可以了吗?这种方法确实可行,但对已经分好组的数据再进行一次分组,是没有任何必要的。1,2,3,4,5,6,7 <-- 根据规则 i<4,{1,2,3} 为一组,{4,5,6,7} 为另一组
2,4,6,8,1,3,5,7,9 <-- 根据规则 i%2=0,{2,4,6,8} 为一组,{1,3,5,7,9} 为另一组
实际上,对于如何在已分好组的数据中找到分界位置,C++ 11标准库提供了专门解决此问题的函数,即 partition_point() 函数。
partition_point() 函数定义在
<algorithm>头文件中,其语法格式为:其中,first 和 last 为正向迭代器,[first, last) 用于指定该函数的作用范围;pred 用于指定数据的筛选规则。ForwardIterator partition_point (ForwardIterator first, ForwardIterator last,
UnaryPredicate pred);
同时,该函数会返回一个正向迭代器,该迭代器指向的是 [first, last] 范围内个不符 pred 筛选规则的元素。所谓筛选规则,其实就是包含 1 个参数且返回值类型为 bool 的函数,此函数可以是一个普通函数,也可以是一个函数对象。
举个例子:
#include <iostream> // std::cout
#include <algorithm> // std::partition_point
#include <vector> // std::vector
using namespace std;
//以普通函数的方式定义筛选规则
bool mycomp(int i) { return (i % 2) == 0; }
//以函数对象的形式定义筛选规则
class mycomp2 {
public:
bool operator()(const int& i) {
return (i % 2 == 0);
}
};
int main() {
vector<int> myvector{ 2,4,6,8,1,3,5,7,9 };
//根据 mycomp 规则,为 myvector 容器中的数据找出分界
vector<int>::iterator iter = partition_point(myvector.begin(), myvector.end(),mycomp);
//输出组的数据
for (auto it = myvector.begin(); it != iter; ++it) {
cout << *it << " ";
}
cout << "\n";
//输出第二组的数据
for (auto it = iter; it != myvector.end(); ++it) {
cout << *it << " ";
}
cout << "\n*iter = " << *iter;
return 0;
}
程序执行结果为:
2 4 6 8
1 3 5 7 9
*iter = 1
通过分析程序并结输出结果可以看到,partition_point() 返回了一个指向元素 1 的迭代器,而该元素为 myvector 容器中个不符 mycomp 规则的元素,同时其也可以第二组数据中个元素。值得一提的是,C++ 11标准库中给出了 partition_point() 函数底层实现的参考代码(如下所示),感兴趣的读者可自行分析,这里不再进行赘述:
template <class ForwardIterator, class UnaryPredicate>
ForwardIterator partition_point (ForwardIterator first, ForwardIterator last,
UnaryPredicate pred)
{
auto n = distance(first,last);
while (n>0)
{
ForwardIterator it = first;
auto step = n/2;
std::advance (it,step);
if (pred(*it)) { first=++it; n-=step+1; }
else n=step;
}
return first;
}
- 随机文章
- 核心危机(核心危机魔石合成攻略)
- 风儿(风儿轻轻的吹)
- 饿了么红包怎么用(饿了么红包怎么用微信支付)
- 儿童教育文章(儿童教育)
- 光遇花手先祖位置(安卓光遇手花先祖)
- 广州4a广告公司(广州4a广告公司创意总监年薪)
- 抖音卡(抖音卡顿怎么解决)
- xboxones(xboxone手柄怎么配对主机)
- 兵马俑(兵马俑介绍和历史背景)
- 帆船比赛(帆船比赛视频)
- 海猫鸣泣之时游戏(海猫鸣泣之时游戏在哪玩)
- 韩国媳妇和小雪(韩国媳妇和小雪的父亲工资是多少)
- 儋州市第二中学(儋州市第二中学录取分数线)
- 鬼泣5攻略(鬼泣5攻略第三关怎么跳)
- 和柳亚子(和柳亚子先生于田)
- yy魔兽(yy魔兽世界)
- 国外成人游戏(国外成人游戏注册需要visa信用卡)
- 充值卡代理(充值卡代理加盟)
- 拆奶罩
- 郭妮小说(恶魔的法则郭妮小说)
- 东天目山(东天目山景区)
- 杭同(杭同培训中心怎么样)
- 蝙蝠给人类的一封信(蝙蝠给人类的一封信)
- 大松电饭煲(美的大松电饭煲)
- 服饰加盟(服饰加盟店招商)
- 疯狂填字(疯狂填字5)
- 点对点短信息(点对点短信息费是什么意思)
- 观音普门品(观音普门品念诵全文)
- 河北省大运会(河北省大运会时间)
- 骇客神条(骇客神条怎么辨别真假)
