变序性算法改变元素的次序,但不改变元素值。这些算法不能用于关联式容器。
1.逆转元素次序
- void reverse( BidirectionIterator sourceBeg, BidirectionIterator sourceEnd)//将区间[beg, end)内的元素全部逆序。
- OutputIterator reverse_copy( BidirectionIterator sourceBeg, BidirectionIterator sourceEnd, BidirectionIterator destBeg)//返回目标区间内最后一个复制元素的下一位置。
- 注:list有自己的成员函数reverse()
2.旋转元素次序
旋转序列内的元素
- void rotate( ForwardIterator beg, ForwardIterator newBeg, ForwardIterator end)//将区间[beg, end) 内的元素进行旋转,执行后*newBeg成为新的第一元素。
- OutputIterator rotate_copy( ForwardIterator sourceBeg, ForwardIterator newBeg, ForwardIterator sourceEnd, OutputIterator destBeg)//将源区间[sourceBeg, sourceEnd )内的元素复制到"以destBeg起始的目标区间"中,同时旋转元素,使newBeg成为新的第一元素。返回目标区间内最后一个被复制元素的下一位置。先旋转,再复制(但不改变source里面的值)。
// STL.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <print.hpp>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
set<int> coll;
INSERT_ELEMENTS(coll,1,9);
PRINT_ELEMENTS(coll);
set<int>::iterator pos=coll.begin();
advance(pos,1);
rotate_copy(coll.begin(),pos,coll.end(),ostream_iterator<int>(cout," "));
cout<<endl;
pos=coll.end();
advance(pos,-2);
rotate_copy(coll.begin(),pos,coll.end(),ostream_iterator<int>(cout," "));
cout<<endl;
set<int>::iterator pos2=coll.end();
advance(pos2,-2);
rotate_copy(coll.begin(),coll.find(2),pos2,ostream_iterator<int>(cout," "));
cout<<endl;
return 0;
}

3.排列元素
- bool next_permutation( BidirectionalIterator beg, BidirectionalIterator end)//改变区间[beg, end) 内的元素次序,使它们符合"下一个排列次序",即升序。如果得以排列成升序,则返回true。
- bool prev_permutation( BidirectionalIterator beg, BidirectionalIterator end)//改变区间[beg, end) 内的元素次序,使它们符合"上一个排列次序",即降序
- 注:如果要走遍所有排列,必须先将所有元素(按升序或降序)排序,然后开始以循环方式调用next_permutation或prev_premutation,直到返回false。
// STL.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <print.hpp>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> coll;
INSERT_ELEMENTS(coll,1,3);
while(next_permutation(coll.begin(),coll.end())){ //当coll为最小时,返回false,退出循环
PRINT_ELEMENTS(coll," ");
}
PRINT_ELEMENTS(coll,"afterward: ");
while(prev_permutation(coll.begin(),coll.end())){ //没有进入循环,此时coll为最小序列
PRINT_ELEMENTS(coll," ");
}
PRINT_ELEMENTS(coll,"now: ");
while (prev_permutation(coll.begin(),coll.end()))
{
PRINT_ELEMENTS(coll," ");
}
PRINT_ELEMENTS(coll,"afterward: ");
return 0;
}

4.重排元素(搅乱次序)
- void random_shuffle( RandomAccessIterator beg, RandomAccessIterator end) //使用一个均匀分布随机数产生器来打乱区间[beg, end)内的元素次序。
- void random_shuffle( RandomAccessIterator beg, RandomAccessIterator end, RandomFunc& op) //使用op打乱区间[beg, end)内的元素次序。op(max)返回一个大于零而小于max的随机数,不包括max本身。
- 注:op是一个non-const reference。不可以将暂时数值或一般函数传进去。
// STL.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <print.hpp>
#include <cstdlib>
using namespace std;
class MyRandom{
public:
ptrdiff_t operator()(ptrdiff_t max){
double tmp;
tmp = static_cast<double>(rand())/static_cast<double>(RAND_MAX);
return static_cast<ptrdiff_t>(tmp*max);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> coll;
INSERT_ELEMENTS(coll,1,9);
PRINT_ELEMENTS(coll,"coll: ");
random_shuffle(coll.begin(),coll.end());
PRINT_ELEMENTS(coll,"shuffled: ");
sort(coll.begin(),coll.end());
PRINT_ELEMENTS(coll,"sorted: ");
MyRandom rd;
random_shuffle(coll.begin(),coll.end(),rd);
PRINT_ELEMENTS(coll,"shuffled: ");
return 0;
}
5.将元素向前搬移
- BidirectionalIterator partition( BidirectionalIterator beg, BidirectionalIterator end, UnaryPredicate op) //将[beg, end)中"造成一元判断式:op(elem)结果为true“的元素向前端移动。返回”令op()结果为false“的第一个元素位置。
- BidirectionalIterator stable_partition( BidirectionalIterator beg, BidirectionalIterator end, UnaryPredicate op) //与partition类似。无论元素是否符合给定的准则,stable_partition()会保持它们之间的相对次序。
// STL.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <print.hpp>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> coll1;
vector<int> coll2;
INSERT_ELEMENTS(coll1,1,9);
INSERT_ELEMENTS(coll2,1,9);
PRINT_ELEMENTS(coll1,"coll1: ");
PRINT_ELEMENTS(coll2,"coll2: ");
cout<<endl;
vector<int>::iterator pos1,pos2;
pos1=partition(coll1.begin(),coll1.end(),not1(bind2nd(modulus<int>(),2))); //partition为双向查找,每次都是将第一个false和最后一个true调换。
pos2=stable_partition(coll2.begin(),coll2.end(),not1(bind2nd(modulus<int>(),2)));
PRINT_ELEMENTS(coll1,"coll1: ");
cout<<"first odd element: "<<*pos1<<endl;
PRINT_ELEMENTS(coll2,"coll2: ");
cout<<"first odd element: "<<*pos2<<endl;
return 0;
}
