STL
Standard Template Library
- STL算法是泛型的(generic),不与任何特定数据结构和对象绑定,不必在环境类似的情况下重写代码
- STL算法可以量身定做,并且具有很高的效率
- STL可以进行扩充,可以编写自己的组建并且能与STL标准的组建进行很好的配合
容器
STL的容器分为两大类: 序列式容器:其中的元素都是可排序的,STL提供了vector、list、deque等序列式容器。 stack、queue、priority_queue是容器适配器,即是说它们是根据deque进行修改产生的。
关联式容器: 每个元素都是由一个键、一个值组成。常见的关联容器如:set、multiset、map、multimap set中key、value唯一,若想重复需使用multiset。
序列容器
#include <iostream>
#include "vector"
#include "list"
#include "queue"
#include "stack"
using namespace std;
struct Display{
void operator()(int i){
cout << i << " ";
}
};
int main() {
int iArr[] = {1,2,3,4,5};
vector<int> iVector(iArr,iArr + 4);
list<int> iList(iArr,iArr + 4);
deque<int> iDeque(iArr,iArr + 4);
for_each(iVector.begin(),iVector.end(),Display());
cout<< endl;
for_each(iList.begin(),iList.end(),Display());
cout<< endl;
for_each(iDeque.begin(),iDeque.end(),Display());
// 队列 先进显出
queue<int> iQueue(iDeque);
// 栈 先进后出
stack<int> iStack(iDeque);
// 优先队列,按优先权
priority_queue<int> iPQueue(iArr,iArr + 4);
cout<< endl;
while(!iQueue.empty()){
cout << "iQueue " << iQueue.front() << " ";
// 出队
iQueue.pop();
}
cout<< endl;
while(!iPQueue.empty()){
// 栈顶
cout << "iPQueue " << iPQueue.top() << " ";
// 出队
iPQueue.pop();
}
cout<< endl;
while(!iStack.empty()){
// 栈顶
cout << "iStack " << iStack.top() << " ";
// 出队
iStack.pop();
}
return 0; // text 代码区
}
关联式容器
#include <iostream>
#include "map"
using namespace std;
struct Display{
void operator()(pair<string,double> info){
cout << info.first << " "<< info.second << endl;
}
};
int main() {
map<string,double> studentScore;
studentScore["LiMing"] = 95.0;
studentScore["LiHong"] = 89.5;
// map 中key的值是唯一的 若有值是修改
studentScore["LiHong"] = 99.5;
studentScore.insert(pair<string,double>("zhang",100));
studentScore.insert(map<string,double>::value_type("wang",94.5));
for_each(studentScore.begin(),studentScore.end(),Display());
cout<< endl;
map<string,double>::iterator iter;
iter = studentScore.find("zhang");
// 找得到就返回,找不到iter就会遍历到尾部
if (iter != studentScore.end()){
cout << "Fount the score is : " << iter ->second << endl;
}else {
cout << "Not find" << endl;
}
iter = studentScore.begin();
// 迭代器遍历删除问题:不能直接删除
while(iter != studentScore.end()){
if (iter->second < 95.0){
// 去除不是小于95.0的元素
// 这里不应该是iter,而应该是iter++
studentScore.erase(iter++);
}else {
iter ++;
}
}
cout << endl;
for_each(studentScore.begin(),studentScore.end(),Display());
// 迭代器遍历删除问题:不能直接删除
for(iter = studentScore.begin();iter != studentScore.end();iter ++){
if (iter ->second < 95){
// 直接删除当前结果是错误的
//studentScore.erase(iter);
// erase删除一个迭代器会返回一个新的迭代器
iter = studentScore.erase(iter);
}
}
for_each(studentScore.begin(),studentScore.end(),Display());
// 通过find得到并删除元素
iter = studentScore.find("zhang");
studentScore.erase(iter);
for_each(studentScore.begin(),studentScore.end(),Display());
// 删除指定元素
int n = studentScore.erase("zhang");
cout << n << endl;
for_each(studentScore.begin(),studentScore.end(),Display());
// 删除所有元素
studentScore.erase(studentScore.begin(),studentScore.end());
for_each(studentScore.begin(),studentScore.end(),Display());
return 0;
}
仿函数
仿函数一般不会单独使用,主要是为了搭配STL算法使用。
本质就是类重载类一个operator(),创建一个行为类似函数的对象。
#include <iostream>
#include "algorithm"
using namespace std;
template<class T>
inline void Display(T const &a){
cout << a << " " <<endl;
};
template<class T>
bool MySort(T const &a, T const &b){
return a > b;
};
template<class T>
struct SortF{
inline bool operator()(T const &a ,T const &b)const{
return a > b;
}
};
template<class T>struct DisplayF{
inline void operator()(T const &a)const{
cout << a << " ";
}
};
int main() {
int arr[] = {4,3,2,1,7};
sort(arr,arr+5, MySort<int>);
for_each(arr,arr+5,Display<int>);
// C++放函数模版
int arr2[] = {4,3,2,1,77};
sort(arr2,arr2+5, SortF<int>());
for_each(arr2,arr2+5,DisplayF<int>());
return 0;
}
算法 algorithm
STL中算法大致分为四类
- 非可变序列算法:指不可以修改它们所操作的容器内容的算法
- 可变序列算法:指可以修改它们所操作的容器内容的算法
- 排序算法:包括对序列进行排序和合并的算法、搜索算法、及有序序列上的集合操作
- 数值算法:对容器内容进行数值计算
主要在algorithm、functional、numeric包中
#include <iostream>
#include "algorithm"
#include "functional"
using namespace std;
int main() {
int arr[] = {1,2,3,4,5};
int arr2[] = {10,20,30,40,50};
int results[5];
transform(arr,arr+5,arr2,results,std::plus<int>());
// lambda 表达式 [外部传入参数](使用参数) -> void {}
for_each(results,results+5,[](int a){ cout << a <<" ";});
return 0;
}