首先使用STL算法,有几个头文件需要说明下
#include //算法
#include //数值处理
#include //仿函数或函数适配器
void square(int& elem)
{
elem = elem * elem;
}
...
for_each(col.begin(),col.end(), //range
square); //operation
void square(int& elem)
{
elem = elem * elem;
}
...
transform(col.begin(),col.end(), //source range
col.begin(), // destination range
square); //operation
变动性算法如下表所示
1. transform()的速度也许会更慢些,因它是将操作返回值返回给赋值元素,而不是直接变动元素
2. 严格的说merge()不算是变动性算法,因为它要求输入区间必须是以序(sorted)的,然而实用上merge()也可以用来合并无序区间-当然其结果也是无序的
3. 注意关联式容器的元素常被视为常数,因此不可将关联式容器当作变动性算法的目标区间
- 移除性算法
移除性算法是一种特殊的变动性算法,它们可以移除某区间内的元素,也可以在复制过程中执行移除动作。注意和变动性算法一样,其目标区间也不能是关联容器见下图
注意移除算法只是在逻辑上移除元素,手段是:将不需被移除的元素往前覆盖(overwrite)应被移除的元素
- 变序性算法
透过元素值的赋值和交换,改变元素顺序 (但不改变元素值),和变动性算法一样,不能以关联式容器作为目标
- 排序算法
排序算法是一种特殊的变序性算法,但比一般的变序性算法复杂,花费更多时间,需要动用随机存取迭代器。如下
(1) sort()内部采用quicksort算法,复杂度为n*log(n),但最差的情况也可能是n*n
(2)partial_sort()内部采用heap_sort算法,因此它在任何情况下保证n*log(n)复杂度。大多数情况下heapsort比quicksort慢2~5倍,所以大多数情下虽然partial_sort()具有较佳复杂度,但sort()具有较好的执行效率。partial_sort()还有一种特殊能力:如果只需要前n个元素排序,它可以在完成任务后立刻停止,
(3)stable_sort()内部采用mergesort。它对所有元素进行排序。
如果只需排序后的第n个元素,或只需要令最先或最后的n个元素(无序)就位,可以使用nth_element()。
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn)
{
while (first!=last)
{
fn (*first);
++first;
}
return fn;
}
#include
#include
#include
using namespace std;
template<typename T>
inline void INSERT_ELEMENTS(T& col, int first, int last)
{
for (int i=first; i<=last; ++i)
col.insert(col.end(),i);
}
void print(int elem)
{
cout << elem << ' ';
}
int main(void)
{
vector<int> col;
INSERT_ELEMENTS(col,1,9);
for_each(col.begin(), col.end(), print);
return 0;
}
例子2展示如何利用仿函数来改变一个元素内容
#include
#include
#include
#include
using namespace std;
template<typename T> //仿函数
inline void INSERT_ELEMENTS(T& col, int first, int last)
{
for (int i=first; i<=last; ++i)
col.insert(col.end(),i);
}
template<typename T> //仿函数
class AddValue
{
private:
T theValue;
public:
AddValue(const T& v) : theValue(v) {}
void operator() (T& elem) const //注意参数是引用
{
elem += theValue;
}
};
int main(void)
{
vector<int> col;
INSERT_ELEMENTS(col,1,9);
copy(col.begin(),col.end(),ostream_iterator<int>(cout," "));//1 2 3 4 5 6 7 8 9
cout << endl;
for_each(col.begin(), col.end(), AddValue<int>(10));
copy(col.begin(),col.end(),ostream_iterator<int>(cout," "));//11 12 13 14 15 16 17 18 19
cout << endl;
for_each(col.begin(), col.end(), AddValue<int>(*col.begin()));
copy(col.begin(),col.end(),ostream_iterator<int>(cout," "));//22 23 24 25 26 27 28 29 39
cout << endl;
return 0;
}
class AddValue<>定义了一个仿函数,使用仿函数的好处是:可以在执行期间,可以在执行期间传入欲加的数值
例子3展示如何利用for_each()的返回值。由于for_each()能返回一项操作,利用这一项特性,在该项操作中处理返回结果。
#include
#include
#include
#include
using namespace std;
template<typename T>
inline void INSERT_ELEMENTS(T& col, int first, int last)
{
for (int i=first; i<=last; ++i)
col.insert(col.end(),i);
}
class MeanValue
{
private:
long num;
long sum;
public:
MeanValue() : num(0), sum(0){}
void operator() (int elem)
{
num++;
sum += elem;
}
operator double()
{
return static_cast<double>(sum) / static_cast<double>(num);
}
};
int main(void)
{
vector<int> col;
INSERT_ELEMENTS(col,1,8);
double mv = for_each(col.begin(), col.end(), MeanValue());
copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); // 1 2 3 4 5 6 7 8
cout << endl;
cout << "mean value: " << mv << endl;// 4.5
return 0;
}
/*
返回操作就是求平均值,然后利用 重载double()来转换
*/