函数对象:
函数对象是可以以函数方式与()结合使用的任意对象,包括:
1)函数名;
2)指向函数的指针;
3)重载了()操作符的类对象(即定义了函数operator()的类)。
算法:
算法是对迭代器进行操作的,不是对特定的容器。
STL将算法库分为4组,
前3个在algorithm头文件中描述,而第4个在numeric头文件中描述。
1) 非修改式序列操作:不改变容器的内容,如find()、for_each()等。
2) 修改式序列操作:可以修改容器中的内容,如transform()、random_shuffle()、copy等。
3) 排序和相关操作:包括各种排序函数等,如sort()等。
4) 通用数字运算:计算两个容器的内部乘积等。
一、不可修改序列内容的算法:
for_each函数的使用
将一个函数应用于某一范围的元素。
例:
#include <iostream>
#include <vector>
#include <algorithm>
using std::cout;
using std::endl;
using std::vector;
void print(vector<int>::value_type & v){
//print函数。将元素自增2后输出。vector<int>::value_type多余,可以直接写int。传的
是引用,可以改变值。如果不写引用,则改不了。
v += 2;
cout << v << " ";
}
int main(){
vector<int> vecInt = {1, 2, 3, 4, 5, 6};
for_each(vecInt.begin(), vecInt.end(), print);
//将函数print应用于vecInt.begin()到vecInt.end()之间的元素。
cout << endl;
for(auto & elem : vecInt)
//3 4 5 6 7 8 。说明传递的是引用,真的修改了。
cout << elem << " ";
cout << endl;
return 0;
}
二、可以修改序列内容的操作
replace_if的使用
将满足特定条件的元素替换为另一个值。
例1:
#include <iostream>
#include <algorithm>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
int main(void){
vector<int> vecInt = {1, 2, 3, 4, 5, 6};
std::less<int> lt;
//二元断言。断言理解为返回bool型的一个函数。二元就是需要两个参数
replace_if(vecInt.begin(), vecInt.end(), bind1st(lt,3), 7);
//bind1st是一个函数适配器。将3与lt的第一个参数进行绑定。lt需要两个参
数,当第一个参数小于第二个参数时,返回true。所以当3小于元素时,返
回true;当3大于元素时,返回false.当返回true时满足条件,会将元素替换为7
for(auto & elem : vecInt)
//输出1 2 3 7 7 7
cout << elem << " ";
return 0;
}
remove_if的使用
例1:迭代器失效的情况
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using std::cout;
using std::endl;
using std::vector;
using std::string;
int main(void){
vector<string> vecStr;
vecStr.push_back("hello");
int i = 0;
auto it = vecStr.begin();
//auto关键字。该句相当于:vector<string>::iterator it; it = vec.begin();
it指向一块存
储区的位置。
for(; it != vecStr.end(); ++it){
cout << vecStr.capacity() << endl;
//第一次进来时,capacity为1
cout << *it << endl;
if(0 == i){
vecStr.push_back("world");
//容器插入元素"world".此时底层做了扩容的操作, 另开辟了一块空间,存放元素。
而迭代器it还是指向了原来的空间。当执行++it时,出错。
cout << "vecStr.push !" << endl;
i = 1;
}
}
}
例2:erase-remove惯用法
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using std::cout;
using std::endl;
using std::vector;
using std::string;
int main(void){
vector<int> vecInt;
vecInt.reserve(10);
cout << vecInt.size() << endl; //0
cout << vecInt.capacity() << endl; //10
for(int idx = 1; idx <= 10; ++idx){
vecInt.push_back(idx);
}
vecInt[3] = vecInt[5] = vecInt[9] = 99;
for(auto & elem : vecInt)
cout << elem << " "; //1 2 3 99 5 99 7 8 9 99
cout << endl;
vecInt.erase(std::remove(vecInt.begin(), vecInt.end(), 99),vecInt.end());
//remove(vecInt.begin(),vecInt.end,99)之后指针指向的位置之后
的元素就不要了。需要erase。这样的用法叫做:erase-remove
惯用法。remove不直接删掉就是因为害怕出现迭代器失效的问
题。所以remove不直接删除数据,而是尽量往后移动,移完之
后再统一删除。
cout << "删除99之后:" << endl;
for(auto & elem : vecInt)
cout << elem << " ";
cout << endl;
}
三、分块操作、排序操作、二叉排序操作
四、集合操作、堆操作
五、最小最大操作、数字操作、C库