STL学习笔记(变序性算法)

变序性算法改变元素的次序,但不改变元素值。

这些算法不能用于关联式容器,因为在关联式容器中,元素有一定的次序,不能随意变动。

 

逆转元素次序

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 }
View Code

 

 

旋转(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 }
View Code

 

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 }
View Code

 

 

排列元素(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 }
View Code

 

 

重排元素(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 }
View Code

 

 

将元素向前搬移

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 }
View Code

 

posted @ 2015-09-29 14:01  Runnyu  阅读(259)  评论(0编辑  收藏  举报