STL算法众多,很难一一概括,对于我们日常软件开发而言,其实也不需要全部掌握,我们只需要掌握其中最常用的算法并能熟练使用即可。
查找算法
- count:利用等于操作符,把标志范围内的元素与输入值比较,返回相等元素个数;
- count_if:利用输入操作赋,对标志范围内的元素进行操作,返回结果为true的个数;
- equal_range:功能类似equal,返回一对iterator,第一个表示lower_bound,第二个表示upper_bound;
- find:利用底层元素的等于操作赋,对指定范围内的元素与输入值进行比较,当匹配时,结束搜索,并返回指向该元素的iterator;
- find_if:使用输入的函数代替等于操作符执行find;
相关实例代码如下:
#include <algorithm>
#include <vector>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
vector<int> vec;
for (int i = 0; i < 20; ++i)
{
int value = rand() % 10;
cout << "value" << i << ":" << value << endl;
vec.push_back(value);
}
//count
cout << "count(== 5):" << count(vec.begin(), vec.end(), 5) << endl;
//count_if
cout << "count(< 5)" << count_if(vec.begin(), vec.end(), bind2nd(less<int>(), 5)) << endl;
auto between = [](int value)->bool {
if (value > 5 && value < 15)
return true;
else
return false;
};
cout << "count(5 < ... < 15)" << count_if(vec.begin(),vec.end(),between) << endl;
//equal_range
typedef vector<int>::iterator iterator;
pair<iterator,iterator> pairIter;
cout << "pairIter.first:" << *(pairIter.first) << endl;
cout << "pairIter.second:" << *(pairIter.second) << endl;
//find
cout << "find(5)" << *find(vec.begin(),vec.end(),5);
//find_if
cout << "find_if( > 5)" << *find_if(vec.begin(),vec.end(),bind2nd(greater<int>(),5));
return 0;
}
需要注意以下几点:
- equal_range最好针对有序序列进行查找,否则很有可能找不到;
- 类似于count_if()、find_if()这种函数,其第三个参数,我们可以使用普通函数,也可以使用lambda函数,也可以使用仿函数,当条件只是大于小于时,less<>()、greater<>()是最佳选择;
排序算法
- reverse:将指定范围内的元素反序排序;
- sort:以升序重新排列指定范围内的元素。重载版本使用自定义的比较操作。
相关实例代码如下:
#include <algorithm>
#include <stdlib.h>
#include <vector>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
vector<int> vec;
for (int i = 0; i < 20; ++i)
{
int value = rand() % 10;
cout << "value" << i << ":" << value << endl;
vec.push_back(value);
}
//reverse
reverse(vec.begin(),vec.end());
//sort
sort(vec.begin(),vec.end(),bind2nd(greater<int>(),5));
return 0;
}
需要注意以下几点:
- STL中通用的排序算法只能适用于随机存取迭代器,因此list不能调用,但是list自定义了其sort排序算法;
- 对于sort函数,自定义比较器时,如果return (first < second),那么意味着符合升序,对于不符合这种序列的元素,sort函数都将交换位置,return (first < second)则相反。参考:如何自定义sort函数中的比较函数。
删除算法
- remove:删除指定范围内所有等于指定元素的元素;
- remove_If:删除指定范围内所有符合条件的元素;
相关实例代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
vector<int> vec;
for (int i = 0; i < 10; ++i)
vec.push_back(rand() % 5);
//remove
remove(vec.begin(),vec.end(),5);
//remove_if
remove_if(vec.begin(),vec.end(),bind2nd(greater<int>(),5));
return 0;
}
需要注意以下几点:
- 两个算法都返回变动后的序列新的逻辑终点,也就是最后一个未被移除元素的下一位置,我们应当使用这个新的逻辑重点取代原始终点end(),但在移除过程后begin()仍然可用,因为算法会把原本置于后面的未移除元素向前移动,以覆盖被移除元素;
- 由于会发生元素变动,所以这些算法不能用于关联式容器,但是关联式容器提供了成员函数erase();
- list提供了一个等效成员函数remove():不是重新赋值元素,而是重新安排指针,因此具有更佳性能;
替换算法
- replace:将指定范围内所有等于指定元素的元素使用新元素代替;
- replace_if:将指定范围内所有符合条件的元素都用新元素代替;
- swap:交换存储在两个对象中的值;
相关实例代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
vector<int> vec;
for (int i = 0; i < 10; ++i)
vec.push_back(rand() % 5);
//replace
replace(vec.begin(),vec.end(),5,10);
//replace_if
replace_if(vec.begin(),vec.end(),bind2nd(greater<int>(),5),10);
//swap
int a = 10;
int b = 5;
swap(a,b);
return 0;
}
需要注意以下几点:
- swap()函数的最大优势在于,通过模板特化或者函数重载,我们可以为更复杂的性别提供特殊的实用版本,我们交换对象内部成员,不必反复赋值,这无疑将会大大节约时间,但需要注意,STL提供的swap只是一个浅拷贝,如果需要深拷贝,需要我们自己实现;但无论如何,swap()函数操作带来效率上的提升是毋庸置疑的,对于我们自定义的性别,我们应当尽量提供swap()特化版本;
for_each()算法
for_each()算法非常灵活,它可以以不同的方式存取、处理、修改每一个元素;代码示例如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
void print_elem(int value)
{
cout << value << endl;
}
int main()
{
vector<int> vec;
for (int i = 0; i < 10; ++i)
vec.push_back(rand() % 5);
for_each(vec.begin(),vec.end(),print_elem);
return 0;
}
以上就是STL中最常用的几种算法,其他STL算法相对而言使用率较少,如果想要更加全面的了解STL算法,可以参考下面这篇博客:参考链接。