下面我要介绍的是STL算法中,用来进行按条件除去容器内元素的通用算法,也就是所有容器都适用的方法.
#include <iostream>
#include <algorithm>
#include <functional>
#include <list>
using namespace std;
template <typename T>
class Print
{
public:
void operator()(T a)
{
cout << a << " ";
}
};
int main()
{
list<int> s = {1,9,5,4,2,6,5,7};
//remove算法,除去使第三个参数的值为true的元素.
//注意,不管是什么算法,是不可能对原容器的元素的数量进行改变的,换句话说,就是算法不可能对容器进行增加元素或者删除元素的操作,所以remove算法只是把原容器的元素进行了筛选重组了而已,元素的数量还是原来的数量.
list<int>::iterator pos = remove(s.begin(), s.end(), 5);
for_each(s.begin(), s.end(), Print<int>());//1 9 4 2 6 7 5 7
cout << endl;
//容器内元素的增减只能通过容器自身所带的函数,比如:erase()或insert(),addpend()等等.
s.erase(pos,s.end());
for_each(s.begin(),s.end(),Print<int>());//1 9 4 2 6 7
cout << endl;
system("pause");
return 0;
}
下面是remove的实现,当然跟SGI STL版本的源码不同,它直接用调用了remove_copy算法,但我们还没介绍到,我觉得这样的实现更方便理解.
template <typename T, typename V>
T myRemove(T first, T last, V value)
{
T temp = first;
while (temp != last)
{
//把值不同的元素给赋值到原容器的头开始,也就是第一个元素开始重新赋值,所以原容器最后会留下残余,当然这很好解决.看返回值.
if (*temp != value)
{
*first = *temp;
first++;
}
temp++;
}
//我们返回了原容器准备被继续赋值的下一个迭代器,也就是相当于知道了被赋值元素的个数,因为容器的erase()成员函数参数是迭代器,所以还是返回迭代器比较方便.
return first;
}
remove解决后,就是remove_copy算法了,这个算法比较常用,我就不举例子了,直接写它的实现代码了:
//其实并没有什么不同,只是赋值给了别的容器.
//注意,凡是带copy的算法,拷贝进元素的容器必须要先resize足够的空间,否则当赋值时是会报错的!!!
template<typename T, typename V>
T myRemove_copy(T first, T last, T new_first, V value)
{
while (first != last)
{
if (*first != value)
{
*new_first = *first;
new_first++;
}
first++;
}
return new_first;
}
又到了remove_if算法了,其实是否有if,就是看你对元素的要求了,如果只是单纯删除某个元素,就用不到if了,当然也不是不能用…只是小题大做,浪费时间而已,如果要对容器内的元素进行区间的操作,也就是涉及到多个元素的操作,那么基本都要带if了…而且就和实现也没什么俩样,只是多了个函数的形式来取值.下面是remove_if的例子和剩下的remove算法实现.
#include <iostream>
#include <algorithm>
#include <functional>
#include <list>
using namespace std;
template <typename T>
class Print
{
public:
void operator()(T a)
{
cout << a << " ";
}
};
int main()
{
list<int> s = { 1, 9, 5, 4, 2, 6, 5, 7 };
//第三个参数可以看成是:如果元素>5,则返回true,否则返回false,这是个仿函数和配接器的配套使用.只能用于简单的操作,一些比较复杂的东西还是要自己去定制一个模板类,去重载()操作符滴...
list<int>::iterator pos = remove_if(s.begin(), s.end(), bind2nd(greater<int>(), 5));
for_each(s.begin(), s.end(), Print<int>());// 1 5 4 2 5 6 5 7
cout << endl;
s.erase(pos, s.end());
for_each(s.begin(), s.end(), Print<int>());// 1 5 4 2 5
cout << endl;
system("pause");
return 0;
}
remove_if和remove_copy_if的实现.
template <typename T, typename C>
T myRemove_if(T first, T last,C function)
{
T temp = first;
while (temp != last)
{
if (!function(*temp))
{
*first = *temp;
first++;
}
temp++;
}
return first;
}
template <typename T, typename C>
T myRemove_copy_if(T first, T last,T new_first, C function)
{
while (first != last)
{
if (!function(*first))
{
*new_first = *first;
new_first++;
}
first++;
}
return new_first;
}
今天介绍的也挺多的了,明天会介绍下partition和stable_partition…