# Benjamin

## STL算法(Algorithms):修改操作(拷贝、替换等)

Stl的函数对象的写操作：
copy、copy_backward、swap、swap_ranges、iter_swap、transform、
replace、replace_if、replace_copy、replace_copy_if、fill、fill_n、
generate、generate_n、remove、remove_if、remove_copy、remove_copy_if、
unique、unique_copy、reverse、reverse_copy、rotate、rotate_copy、
random_shuffle、partition、stable_partition
1. 拷贝：copy和copy_backward
Copy的原型：
template <class InputIterator, class OutputIterator>
OutputIterator copy ( InputIterator first, InputIterator last, OutputIterator result );
copy_backward原型：
template <class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 copy_backward ( BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result );

copy_backward和下面的代码等效
template<class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 copy_backward ( BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result )
{
while (last!=first) *(--result) = *(--last);
return result;
}
Copy和下面的代码等效
template<class InputIterator, class OutputIterator>
OutputIterator copy ( InputIterator first, InputIterator last, OutputIterator result )
{
while (first!=last) *result++ = *first++;
return result;
}
copy例子：
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
int myints[]={10,20,30,40,50,60,70};
vector<int> myvector;
vector<int>::iterator it;

myvector.resize(7);   // allocate space for 7 elements

copy ( myints, myints+7, myvector.begin() );

cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
copy_backward例子：
// copy_backward example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
vector<int> myvector;
vector<int>::iterator it;

// set some values:
for (int i=1; i<=5; i++)
myvector.push_back(i*10);          // myvector: 10 20 30 40 50

myvector.resize(myvector.size()+3);  // allocate space for 3 more elements

copy_backward ( myvector.begin(), myvector.begin()+5, myvector.end() );

cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}

2、交换：swap、swap_ranges、iter_swap
Swap交换两个对象的值；swap_ranges是交换连个范围内的值；
iter_swap通过迭代器交换两个对象指针的值

// swap algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {

int x=10, y=20;                         // x:10 y:20
swap(x,y);                              // x:20 y:10

vector<int> first (4,x), second (6,y);  // first:4x20 second:6x10
swap(first,second);                     // first:6x10 second:4x20

cout << "first contains:";
for (vector<int>::iterator it=first.begin(); it!=first.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// swap_ranges example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
vector<int> first (5,10);        //  first: 10 10 10 10 10
vector<int> second (5,33);       // second: 33 33 33 33 33
vector<int>::iterator it;

swap_ranges(first.begin()+1, first.end()-1, second.begin());

// print out results of swap:
cout << " first contains:";
for (it=first.begin(); it!=first.end(); ++it)
cout << " " << *it;

cout << "\nsecond contains:";
for (it=second.begin(); it!=second.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// iter_swap example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {

int myints[]={10,20,30,40,50 };          //   myints:  10  20  30  40  50
vector<int> myvector (4,99);             // myvector:  99  99  99  99

iter_swap(myints,myvector.begin());      //   myints: [99] 20  30  40  50
// myvector: [10] 99  99  99

iter_swap(myints+3,myvector.begin()+2);  //   myints:  99  20  30 [99]
// myvector:  10  99 [40] 99

cout << "myvector contains:";
for (vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
3、替换: replace、replace_if、replace_copy、replace_copy_if
replace是简单的值替换；replace_if是有条件的替换；
replace_copy是替换并重新输出到另一个序列中；
replace_copy_if和上面的功能类似，不过有条件；

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
vector<int> myvector (myints, myints+8);            // 10 20 30 30 20 10 10 20

replace (myvector.begin(), myvector.end(), 20, 99); // 10 99 30 30 99 10 10 99

cout << "myvector contains:";
for (vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// replace_if example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool IsOdd (int i) { return ((i%2)==1); }

int main () {
vector<int> myvector;
vector<int>::iterator it;

// set some values:
for (int i=1; i<10; i++) myvector.push_back(i);          // 1 2 3 4 5 6 7 8 9

replace_if (myvector.begin(), myvector.end(), IsOdd, 0); // 0 2 0 4 0 6 0 8 0

cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}

// replace_copy example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };

vector<int> myvector (8);
replace_copy (myints, myints+8, myvector.begin(), 20, 99);

cout << "myvector contains:";
for (vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// replace_copy_if example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool IsOdd (int i) { return ((i%2)==1); }

int main () {
vector<int> first,second;
vector<int>::iterator it;

// set some values:
for (int i=1; i<10; i++) first.push_back(i);          // 1 2 3 4 5 6 7 8 9

second.resize(first.size());   // allocate space
replace_copy_if (first.begin(), first.end(), second.begin(), IsOdd, 0);
// 0 2 0 4 0 6 0 8 0

cout << "second contains:";
for (it=second.begin(); it!=second.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}

4、初始化：fill、fill_n、generate、generate_n
fill和fill_n类似于memset；
generate和generate_n通过函数来产生每个值。

// fill algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
vector<int> myvector (8);                       // myvector: 0 0 0 0 0 0 0 0

fill (myvector.begin(),myvector.begin()+4,5);   // myvector: 5 5 5 5 0 0 0 0
fill (myvector.begin()+3,myvector.end()-2,8);   // myvector: 5 5 5 8 8 8 0 0

cout << "myvector contains:";
for (vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// fill_n example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
vector<int> myvector (8,10);        // myvector: 10 10 10 10 10 10 10 10

fill_n (myvector.begin(),4,20);     // myvector: 20 20 20 20 10 10 10 10
fill_n (myvector.begin()+3,3,33);   // myvector: 20 20 20 33 33 33 10 10

cout << "myvector contains:";
for (vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// generate algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;

// function generator:
int RandomNumber () { return (rand()%100); }

// class generator:
struct c_unique {
int current;
c_unique() {current=0;}
int operator()() {return ++current;}
} UniqueNumber;

int main () {
srand ( unsigned ( time(NULL) ) );

vector<int> myvector (8);
vector<int>::iterator it;

generate (myvector.begin(), myvector.end(), RandomNumber);

cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

generate (myvector.begin(), myvector.end(), UniqueNumber);

cout << "\nmyvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// generate_n example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int current(0);
int UniqueNumber () { return ++current; }

int main () {
int myarray[9];

generate_n (myarray, 9, UniqueNumber);

cout << "myarray contains:";
for (int i=0; i<9; ++i)
cout << " " << myarray[i];

cout << endl;
return 0;
}
5、转换：transform(适用于对某个序列内的每个成员进行的某个操作)

OutputIterator transform ( InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperator op );

template < class InputIterator1, class InputIterator2,
class OutputIterator, class BinaryOperator >
OutputIterator transform ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, OutputIterator result,
BinaryOperator binary_op );

// transform algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int op_increase (int i) { return ++i; }
int op_sum (int i, int j) { return i+j; }

int main () {
vector<int> first;
vector<int> second;
vector<int>::iterator it;

// set some values:
for (int i=1; i<6; i++) first.push_back (i*10); //  first: 10 20 30 40 50

second.resize(first.size());     // allocate space
transform (first.begin(), first.end(), second.begin(), op_increase);
// second: 11 21 31 41 51

transform (first.begin(), first.end(), second.begin(), first.begin(), op_sum);
//  first: 21 41 61 81 101

cout << "first contains:";
for (it=first.begin(); it!=first.end(); ++it)
cout << " " << *it;

cout << endl;
return 0;
}
6、删除：remove、remove_if、remove_copy、remove_copy_if、unique、unique_copy
remove：从序列中删除某个元素

ForwardIterator remove ( ForwardIterator first, ForwardIterator last,
const T& value );
remove_if：将符合条件的都删除掉；remvoe和remove删除后，序列的长度会有变化(减少)

ForwardIterator remove_if ( ForwardIterator first, ForwardIterator last,
Predicate pred );
remove_copy：将删除后的序列拷贝到另外一个序列中

OutputIterator remove_copy ( InputIterator first, InputIterator last,
OutputIterator result, const T& value );
remove_copy_if：基本功能和remove_copy类似，不过这里是有条件的删除

OutputIterator remove_copy_if ( InputIterator first, InputIterator last,
OutputIterator result, Predicate pred );
unique：删除连续的重复的元素

ForwardIterator unique ( ForwardIterator first, ForwardIterator last );

template <class ForwardIterator, class BinaryPredicate>
ForwardIterator unique ( ForwardIterator first, ForwardIterator last,
BinaryPredicate pred );
unique_copy：将删除连续的重复的元素后的序列拷贝到另一个序列中

OutputIterator unique_copy ( InputIterator first, InputIterator last,
OutputIterator result );

template <class InputIterator, class OutputIterator, class BinaryPredicate>
OutputIterator unique_copy ( InputIterator first, InputIterator last,
OutputIterator result, BinaryPredicate pred );

// remove algorithm example
#include <iostream>
#include <algorithm>
using namespace std;

int main () {
int myints[] = {10,20,30,30,20,10,10,20};      // 10 20 30 30 20 10 10 20

// bounds of range:
int* pbegin = myints;                          // ^
int* pend = myints+sizeof(myints)/sizeof(int); // ^                       ^

pend = remove (pbegin, pend, 20);              // 10 30 30 10 10 ?  ?  ?
// ^              ^
cout << "range contains:";
for (int* p=pbegin; p!=pend; ++p)
cout << " " << *p;

cout << endl;

return 0;
}
// remove_if example
#include <iostream>
#include <algorithm>
using namespace std;

bool IsOdd (int i) { return ((i%2)==1); }

int main () {
int myints[] = {1,2,3,4,5,6,7,8,9};            // 1 2 3 4 5 6 7 8 9

// bounds of range:
int* pbegin = myints;                          // ^
int* pend = myints+sizeof(myints)/sizeof(int); // ^                 ^

pend = remove_if (pbegin, pend, IsOdd);        // 2 4 6 8 ? ? ? ? ?
// ^       ^
cout << "range contains:";
for (int* p=pbegin; p!=pend; ++p)
cout << " " << *p;

cout << endl;

return 0;
}
// remove_copy example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
int myints[] = {10,20,30,30,20,10,10,20};          // 10 20 30 30 20 10 10 20
vector<int> myvector (8);
vector<int>::iterator it;

remove_copy (myints,myints+8,myvector.begin(),20); // 10 30 30 10 10 0 0 0

cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// remove_copy_if example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool IsOdd (int i) { return ((i%2)==1); }

int main () {
int myints[] = {1,2,3,4,5,6,7,8,9};
vector<int> myvector (9);
vector<int>::iterator it;

remove_copy_if (myints,myints+9,myvector.begin(),IsOdd);

cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// unique algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool myfunction (int i, int j) {
return (i==j);
}

int main () {
int myints[] = {10,20,20,20,30,30,20,20,10};    // 10 20 20 20 30 30 20 20 10
vector<int> myvector (myints,myints+9);
vector<int>::iterator it;

// using default comparison:
it = unique (myvector.begin(), myvector.end()); // 10 20 30 20 10 ?  ?  ?  ?
//                ^

myvector.resize( it - myvector.begin() );       // 10 20 30 20 10

// using predicate comparison:
unique (myvector.begin(), myvector.end(), myfunction);   // (no changes)

// print out content:
cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// unique_copy example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool myfunction (int i, int j) {
return (i==j);
}

int main () {
int myints[] = {10,20,20,20,30,30,20,20,10};
vector<int> myvector (9);                            // 0  0  0  0  0  0  0  0  0
vector<int>::iterator it;

// using default comparison:
it=unique_copy (myints,myints+9,myvector.begin());   // 10 20 30 20 10 0  0  0  0
//                ^

sort (myvector.begin(),it);                          // 10 10 20 20 30 0  0  0  0
//                ^

// using predicate comparison:
it=unique_copy (myvector.begin(), it, myvector.begin(), myfunction);
// 10 20 30 20 30 0  0  0  0
//          ^

myvector.resize( it - myvector.begin() );            // 10 20 30

// print out content:
cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
7、更改序列内元素的顺序：reverse、reverse_copy、rotate、rotate_copy、random_shuffle、
reverse：反转序列

void reverse ( BidirectionalIterator first, BidirectionalIterator last);
reverse_copy：将反转后的序列拷贝

template <class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy ( BidirectionalIterator first,
BidirectionalIterator last, OutputIterator result );
rotate：旋转元素(将指定范围内的元素移到尾部，其他的元素相对前移)

void rotate ( ForwardIterator first, ForwardIterator middle,
ForwardIterator last );
rotate_copy：将元素旋转后并拷贝

OutputIterator rotate_copy ( ForwardIterator first, ForwardIterator middle,
ForwardIterator last, OutputIterator result );
random_shuffle：重排序列内的随机元素

void random_shuffle ( RandomAccessIterator first, RandomAccessIterator last );

template <class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle ( RandomAccessIterator first, RandomAccessIterator last,
RandomNumberGenerator& rand );

// reverse algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
vector<int> myvector;
vector<int>::iterator it;

// set some values:
for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

reverse(myvector.begin(),myvector.end());       // 9 8 7 6 5 4 3 2 1

// print out content:
cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// reverse_copy example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
int myints[] ={1,2,3,4,5,6,7,8,9};
vector<int> myvector;
vector<int>::iterator it;

myvector.resize(9);

reverse_copy (myints, myints+9, myvector.begin());

// print out content:
cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// rotate algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
vector<int> myvector;
vector<int>::iterator it;

// set some values:
for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

rotate(myvector.begin(),myvector.begin()+3,myvector.end());
// 4 5 6 7 8 9 1 2 3

// print out content:
cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// rotate_copy algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
int myints[] = {10,20,30,40,50,60,70};

vector<int> myvector;
vector<int>::iterator it;

myvector.resize(7);

rotate_copy(myints,myints+3,myints+7,myvector.begin());

// print out content:
cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// random_shuffle example
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;

// random generator function:
ptrdiff_t myrandom (ptrdiff_t i) { return rand()%i;}

// pointer object to it:
ptrdiff_t (*p_myrandom)(ptrdiff_t) = myrandom;

int main () {
srand ( unsigned ( time (NULL) ) );
vector<int> myvector;
vector<int>::iterator it;

// set some values:
for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

// using built-in random generator:
random_shuffle ( myvector.begin(), myvector.end() );

// using myrandom:
random_shuffle ( myvector.begin(), myvector.end(), p_myrandom);

// print out content:
cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
8、分割序列：partition、stable_partition
partition：按照pred制定的规则对序列进行分割

BidirectionalIterator partition ( BidirectionalIterator first,
BidirectionalIterator last, Predicate pred );
stable_partition：基本功能和上面的类似，不同的是分割后的序列都是排序过的(顺序)

// partition algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool IsOdd (int i) { return (i%2)==1; }

int main () {
vector<int> myvector;
vector<int>::iterator it, bound;

// set some values:
for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

bound = partition (myvector.begin(), myvector.end(), IsOdd);

// print out content:
cout << "odd members:";
for (it=myvector.begin(); it!=bound; ++it)
cout << " " << *it;

cout << "\neven members:";
for (it=bound; it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}
// stable_partition example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool IsOdd (int i) { return (i%2)==1; }

int main () {
vector<int> myvector;
vector<int>::iterator it, bound;

// set some values:
for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

bound = stable_partition (myvector.begin(), myvector.end(), IsOdd);

// print out content:
cout << "odd members:";
for (it=myvector.begin(); it!=bound; ++it)
cout << " " << *it;

cout << "\neven members:";
for (it=bound; it!=myvector.end(); ++it)
cout << " " << *it;

cout << endl;

return 0;
}

posted on 2012-02-05 21:39 Benjamin 阅读(949) 评论(0)  编辑 收藏 引用 所属分类: 泛型编程

 只有注册用户登录后才能发表评论。 相关文章: