变序性算法改变元素的次序,但不改变元素值。
这些算法不能用于关联式容器,因为在关联式容器中,元素有一定的次序,不能随意变动。
逆转元素次序
void
reverse(BidirectionalIterator beg,BidirectionalIterator end)
OutputIterator
reverse_copy(BidirectionalIterator sourceBeg,BidirectionalIterator sourceEnd,
OutputIterator destBeg)
1.reverce()会将区间[beg,end)内的元素全部逆序
2.reverse_copy()是reverse()跟copy()的组合
下面这个程序展示reverse()和reverse_copy()的用法
1 #include <iterator> 2 #include "algostuff.hpp" 3 using namespace std; 4 5 int main() 6 { 7 vector<int> coll; 8 INSERT_ELEMENTS(coll,1,9); 9 PRINT_ELEMENTS(coll,"coll: "); 10 reverse(coll.begin(),coll.end()); 11 PRINT_ELEMENTS(coll,"coll: "); 12 reverse(coll.begin()+1,coll.end()-1); 13 PRINT_ELEMENTS(coll,"coll: "); 14 reverse_copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," ")); 15 cout<<endl; 16 }
旋转(Rotating)元素次序
1.旋转序列内的元素
void
rotate(ForwardIterator beg,ForwardIterator newBeg,
ForwardIterator end)
1.将区间[beg,end)内的元素进行旋转,执行后*newBeg成为新的第一元素
2.调用者必须确保newBeg是[beg,end)内的一个有效位置,否则会引发未定义的行为
以下程序示范如何使用rotate()
1 #include "algostuff.hpp" 2 using namespace std; 3 4 int main() 5 { 6 vector<int> coll; 7 INSERT_ELEMENTS(coll,1,9); 8 PRINT_ELEMENTS(coll,"coll: "); 9 rotate(coll.begin(),coll.begin()+1,coll.end()); 10 PRINT_ELEMENTS(coll,"one left: "); 11 rotate(coll.begin(),coll.end()-2,coll.end()); 12 PRINT_ELEMENTS(coll,"two right: "); 13 rotate(coll.begin(),find(coll.begin(),coll.end(),4),coll.end()); 14 PRINT_ELEMENTS(coll,"4 first: "); 15 }
2.复制并同时旋转元素
OutputIterator
rotate_copy(ForwardIterator sourceBeg,ForwardIterator newBeg,
ForwardIterator sourceEnd,
OutputIterator destBeg)
这是copy()和rotate()的组合
以下程序示范rotate_copy()的用法
1 #include <iterator> 2 #include "algostuff.hpp" 3 using namespace std; 4 5 int main() 6 { 7 set<int> coll; 8 INSERT_ELEMENTS(coll,1,9); 9 PRINT_ELEMENTS(coll); 10 set<int>::iterator pos=coll.begin(); 11 advance(pos,1); 12 rotate_copy(coll.begin(),pos,coll.end(),ostream_iterator<int>(cout," ")); 13 cout<<endl; 14 pos=coll.end(); 15 advance(pos,-2); 16 rotate_copy(coll.begin(),pos,coll.end(),ostream_iterator<int>(cout," ")); 17 cout<<endl; 18 rotate_copy(coll.begin(),coll.find(4),coll.end(),ostream_iterator<int>(cout," ")); 19 cout<<endl; 20 }
排列元素(Permuting)元素
bool
next_permutation(BidirectionalIterator beg,
BidirectionalIterator end)
bool
prev_permutation(BidirectionalIterator beg,
BidirectionalIterator end)
1.next_permutation()会改变区间[beg,end)内的元素次序,使他们符合“下一个排列次序”
2.prev_permutation()会改变区间[beg,end)内的元素次序,是他们符合“上一个排列次序”
下面这个例子展示利用next_permutation()和prev_permutation()将所有元素的所有可能排列的过程
1 #include "algostuff.hpp" 2 using namespace std; 3 4 int main() 5 { 6 vector<int> coll; 7 INSERT_ELEMENTS(coll,1,3); 8 PRINT_ELEMENTS(coll,"on entry: "); 9 while(next_permutation(coll.begin(),coll.end())) 10 PRINT_ELEMENTS(coll," "); 11 PRINT_ELEMENTS(coll,"afterward: "); 12 while(prev_permutation(coll.begin(),coll.end())) 13 PRINT_ELEMENTS(coll," "); 14 PRINT_ELEMENTS(coll,"now: "); 15 while(prev_permutation(coll.begin(),coll.end())) 16 PRINT_ELEMENTS(coll," "); 17 PRINT_ELEMENTS(coll,"afterward: "); 18 }
重排元素(Shuffling,搅乱次序)
void
random_shuffle(RandomAccessIterator beg,RandomAccessIterator end)
void
random_shuffle(RandomAccessIterator beg,RandomAccessIterator end,
RandomFunc& op)
1.第一形式使用一个均匀分布随机数产生器来打乱区间[beg,end)内的元素次序
2.第二形式使用op打乱区间[beg,end)内的元素次序。
以下程序示范如何调用random_shuffle()来打乱元素次序
1 #include <cstdlib> 2 #include "algostuff.hpp" 3 using namespace std; 4 5 class MyRandom 6 { 7 public: 8 ptrdiff_t operator()(ptrdiff_t max) 9 { 10 double tmp; 11 tmp=static_cast<double>(rand())/static_cast<double>(RAND_MAX); 12 return static_cast<ptrdiff_t>(tmp * max); 13 } 14 }; 15 16 int main() 17 { 18 vector<int> coll; 19 INSERT_ELEMENTS(coll,1,9); 20 PRINT_ELEMENTS(coll,"coll: "); 21 random_shuffle(coll.begin(),coll.end()); 22 PRINT_ELEMENTS(coll,"shuffled: "); 23 sort(coll.begin(),coll.end()); 24 PRINT_ELEMENTS(coll,"sorted: "); 25 MyRandom rd; 26 random_shuffle(coll.begin(),coll.end(),rd); 27 PRINT_ELEMENTS(coll,"shuffled: "); 28 }
将元素向前搬移
BidirectionalIterator
partition(BidirectionalIterator beg,
BidirectionalIterator end,
UnaryPredicate op)
BidirectionalIterator
stable_partition(BidirectionalIterator beg,
BidirectionalIterator end,
UnaryPredicate op)
1.这两种算法将区间[beg,end)中造成以下一元判断式:op(elem)结果为true的元素向前端移动
2.stable_partition()会保持元素之间的相对次序。
以下程序示范partition()和stable_partition()的用法以及两者的区别
1 #include "algostuff.hpp" 2 using namespace std; 3 4 int main() 5 { 6 vector<int> coll1; 7 vector<int> coll2; 8 INSERT_ELEMENTS(coll1,1,9); 9 INSERT_ELEMENTS(coll2,1,9); 10 PRINT_ELEMENTS(coll1,"coll1: "); 11 PRINT_ELEMENTS(coll2,"coll2: "); 12 cout<<endl; 13 vector<int>::iterator pos1,pos2; 14 pos1=partition(coll1.begin(),coll1.end(),not1(bind2nd(modulus<int>(),2))); 15 pos2=stable_partition(coll2.begin(),coll2.end(),not1(bind2nd(modulus<int>(),2))); 16 PRINT_ELEMENTS(coll1,"coll1: "); 17 cout<<"first odd element: "<<*pos1<<endl; 18 PRINT_ELEMENTS(coll2,"coll1: "); 19 cout<<"first odd elements: "<<*pos2<<endl; 20 PRINT_ELEMENTS(coll2,"coll2: "); 21 }