C++序列操作之std::partition
std::partition会将区间[first,last)中的元素重新排列,满足判断条件pred的元素会被放在区间的前段,不满足pred的元素会被放在区间的后段。该算法不能保证元素的初始相对位置,如果需要保证初始相对位置,应该使用stable_partition.
partition源代码如下:
template<class BidirectionalIterator,class Predicate>
BidirectionalIterator partition(BidirectionalIterator first,BidirectionalIterator last,Predicate pred){
while (true) {
while (true) //从头开始查找满足移动条件的元素
{
if (first==last) //头指针等于尾指针
return first; //直接返回
else if (pred(*first)) //头指针指向值不满足移动条件
++first; //不移动,头指针自加
else
break; //头指针指向的值满足移动条件,跳出循环
}
--last; //尾指针回溯1
while (true) //从尾端查找满足移动条件的元素
{
if (first==last) //头指针等于尾指针
return first; //直接返回
else if(!pred(*last)) //尾指针指向的值不满足移动条件:注意是“!”
--last; //不移动,尾指针自减
else //尾指针所指元素满足移动条件:
break; //跳出循环
}
std::iter_swap(first,last); //将当前头尾指针所指元素进行交换
++first; //头指针自加,进入下一轮循环
}
}
示例:
bool IsOdd (int i) { //用语判断奇数
return (i%2)==1; //奇数返回true,偶数返回0
}
int main(void)
{
std::vector<int> ivec;
for (int i=1; i<10; ++i)
ivec.push_back(i); // 1 2 3 4 5 6 7 8 9
auto bound = partition (ivec.begin(), ivec.end(), IsOdd);
std::cout << "odd elements:";
for (auto it=ivec.begin(); it!=bound; ++it)
std::cout << ' ' << *it; //输出1,9,3,7,5
std::cout << "even elements:";
for (auto it=bound; it!=ivec.end(); ++it)
std::cout << ' ' << *it; //输出6,4,8,2
return 0;
}
PS:未找到stable_partition源代码,貌似不对外开放.