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是正常的拷贝,copy_backward则是从序列的末尾开始拷贝;
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;
}
这个输出的是myvector contains: 10 20 30 10 20 30 40 50
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和上面的功能类似,不过有条件;
注意:这里如果有参数是类对象,则必须重载()
例子:// replace algorithm 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 (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(适用于对某个序列内的每个成员进行的某个操作)
原型:template < class InputIterator, class OutputIterator, class UnaryOperator >
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:从序列中删除某个元素
原型:template < class ForwardIterator, class T >
ForwardIterator remove ( ForwardIterator first, ForwardIterator last,
const T& value );
remove_if:将符合条件的都删除掉;remvoe和remove删除后,序列的长度会有变化(减少)
原型:template < class ForwardIterator, class Predicate >
ForwardIterator remove_if ( ForwardIterator first, ForwardIterator last,
Predicate pred );
remove_copy:将删除后的序列拷贝到另外一个序列中
原型:template <class InputIterator, class OutputIterator, class T>
OutputIterator remove_copy ( InputIterator first, InputIterator last,
OutputIterator result, const T& value );
remove_copy_if:基本功能和remove_copy类似,不过这里是有条件的删除
原型:template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator remove_copy_if ( InputIterator first, InputIterator last,
OutputIterator result, Predicate pred );
unique:删除连续的重复的元素
原型:template <class ForwardIterator>
ForwardIterator unique ( ForwardIterator first, ForwardIterator last );
template <class ForwardIterator, class BinaryPredicate>
ForwardIterator unique ( ForwardIterator first, ForwardIterator last,
BinaryPredicate pred );
unique_copy:将删除连续的重复的元素后的序列拷贝到另一个序列中
原型:template <class InputIterator, class OutputIterator>
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:反转序列
原型:template <class BidirectionalIterator>
void reverse ( BidirectionalIterator first, BidirectionalIterator last);
reverse_copy:将反转后的序列拷贝
原型:<algorithm>
template <class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy ( BidirectionalIterator first,
BidirectionalIterator last, OutputIterator result );
rotate:旋转元素(将指定范围内的元素移到尾部,其他的元素相对前移)
原型:template <class ForwardIterator>
void rotate ( ForwardIterator first, ForwardIterator middle,
ForwardIterator last );
rotate_copy:将元素旋转后并拷贝
原型:template <class ForwardIterator, class OutputIterator>
OutputIterator rotate_copy ( ForwardIterator first, ForwardIterator middle,
ForwardIterator last, OutputIterator result );
random_shuffle:重排序列内的随机元素
原型:template <class RandomAccessIterator>
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制定的规则对序列进行分割
原型:template <class BidirectionalIterator, class Predicate>
BidirectionalIterator partition ( BidirectionalIterator first,
BidirectionalIterator last, Predicate pred );
stable_partition:基本功能和上面的类似,不同的是分割后的序列都是排序过的(顺序)
原型和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;
}