注:编码工具是CLion+Cygwin64
目录
STL概念
全称Standard Template Library,标准模板库,类似于Java的集合框架。
与Java的集合框架不同的是,Java集合框架把集合的所有功能全部封装在集合类中,而C++则把功能拆分到STL包、算法包和迭代器中。
STL下有vector、queue、priority_queue、list、set等容器,全部定义在std命名空间中,如果没有using namespace std声明,则需要以std::vector这样的形式使用。
所有容器均使用了模板,使用时需要指定具体类型。
所有容器均需要导入相应的头文件。
vector
初始化
#include <iostream>
using namespace std;
// 要先导入头文件
#include<vector>
int main(){
vector<int> v;// 默认初始化大小
vector<int> v2(10);// 初始化大小为10
vector<int> v3(10, 0);// 初始化大小为10,元素全部初始化为0
return 0;
}
添加元素
#include <iostream>
using namespace std;
#include<vector>
int main(){
vector<int> v;
// v.begin() 返回vector的迭代器,可以用于遍历,类似于指针,指向vector的最前面
v.insert(v.begin(), 1);
cout << "v.begin()存的值是:" << *v.begin() << endl;
// v.end() 返回vector的迭代器,可以用于遍历,类似于指针,指向vector的最后面
v.insert(v.end(), 2);
cout << "v.end()存的值是:" << *v.end() << endl; // 访问的是系统值
// 插入值到vector尾部
v.push_back(3);
return 0;
}
输出:
v.begin()存的值是:1
v.end()存的值是:-2144185784
访问元素
#include <iostream>
using namespace std;
#include<vector>
int main(){
vector<int> v;
v.push_back(1);
v.push_back(10);
v.push_back(-1);
cout << "第一个元素:" << v.front() << endl;
cout << "最后一个元素:" << v.back() << endl;
cout << "第二个元素:" << v[1] << endl;
return 0;
}
输出:
第一个元素:1
最后一个元素:-1
第二个元素:10
修改元素
#include <iostream>
using namespace std;
#include<vector>
int main(){
vector<int> v;
v.push_back(1);
v.push_back(10);
v.push_back(-1);
v[1] = v[0] * v[2]; // 角标方式修改第二个元素
v.front() = -1;// 修改第一个元素
v.back() = 1;// 修改最后一个元素
cout << v[0] << " " << v[1] << " " << v[2] << endl;
return 0;
}
输出:
-1 -1 1
删除元素
#include <iostream>
using namespace std;
#include<vector>
int main(){
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
// 删除元素,通过迭代器
v.erase(v.begin());
cout << *v.begin() << endl;
return 0;
}
输出:
2
遍历元素
#include <iostream>
using namespace std;
#include<vector>
int main(){
vector<int> v;
v.push_back(1);
v.push_back(10);
v.push_back(100);
// 角标
int i;
for(i = 0; i < v.size(); i ++){
cout << v[i] << " ";
}
cout << endl;
// 迭代器
// for(auto it = v.begin(); it != v.end(); it ++) // auto为自动类型推断
for(vector<int>::iterator it = v.begin(); it != v.end(); it ++)
{
cout << *it << " ";
}
cout << endl;
return 0;
}
输出:
1 10 100
1 10 100
stack
栈的特点:元素后进先出,Last In First Out,LIFO。
stack没有迭代器,也不能用角标访问元素。
#include <iostream>
using namespace std;
// 先导入头文件
#include <stack>
int main(){
stack<int> s;
// 入栈元素
s.push(1);
s.push(100);
s.push(10);
// 获取栈顶元素
int top = s.top();
cout << "top = " << top << endl;
// 遍历
for(;!s.empty();)
{
cout << s.top() << " ";
// 出栈栈顶元素
s.pop();
}
return 0;
}
输出:
top = 10
10 100 1
queue
队列的特点:元素先进先出,First In First Out, FIFO。
queue也没有迭代器,也不能用角标访问元素。
queue的方法和stack类似。
#include <iostream>
using namespace std;
// 先导入头文件
#include <queue>
int main(){
queue<int> q;
// 入队元素
q.push(1);
q.push(100);
q.push(10);
// 获取队首元素
int front = q.front();
cout << "front = " << front << endl;
int back = q.back();
cout << "back = " << back << endl;
// 修改元素
q.front() = 1000;
cout << "front = " << q.front() << endl;
q.back() = 8;
cout << "back = " << q.back() << endl;
// 遍历
for(;!q.empty();)
{
cout << q.front() << " ";
// 出队队首元素
q.pop();
}
return 0;
}
输出:
front = 1
back = 10
front = 1000
back = 8
1000 100 8
priority_queue
优先级队列,会对元素进行排序。其他特性和queue一样,函数和stack类似。
#include <iostream>
using namespace std;
// 先导入头文件
#include <queue>
int main(){
// 也可声明为 priority_queue<int, vector<int>, less<int>> pq;
// 上面的less是一个结构体,里面定义了一个函数,重载了圆括号运算符,返回值是bool,这种函数称为谓词
priority_queue<int> pq;
// 入队元素
pq.push(1);
pq.push(-1);
pq.push(2);
// 遍历
for(;!pq.empty();)
{
cout << pq.top() << " ";
// 出队队首元素
pq.pop();
}
cout << endl;
// 元素从小到大排列
priority_queue<int, vector<int>, greater<int>> pq2;
// 入队元素
pq2.push(1);
pq2.push(-1);
pq2.push(2);
// 遍历
for(;!pq2.empty();)
{
cout << pq2.top() << " ";
// 出队队首元素
pq2.pop();
}
cout << endl;
return 0;
}
输出:
2 1 -1
-1 1 2
list
list有迭代器,但是没有重载中括号运算符,所以不能用角标访问元素。
#include <iostream>
using namespace std;
// 先导入头文件
#include <list>
int main(){
list<int> l;
// 向列表头部插入元素
l.push_front(1);
l.insert(l.begin(), 3);// 类似vector
// 向列表尾部插入元素
l.push_back(2);
l.insert(l.end(), 4);// 类似vector
cout << "第一个元素值:" << l.front() << endl;
cout << "最后一个元素值:" << l.back() << endl;
// 修改列表头部元素值
l.front() = 100;
// 修改列表尾部元素值
l.back() = 1000;
cout << "第一个元素值:" << l.front() << endl;
cout << "最后一个元素值:" << l.back() << endl;
l.push_front(10000);
// 删除列表头部元素值
l.erase(l.begin());
// 遍历列表
for(auto it = l.begin(); it != l.end(); it ++)
{
cout << *it << " ";
}
cout << endl;
return 0;
}
输出:
第一个元素值:3
最后一个元素值:4
第一个元素值:100
最后一个元素值:1000
100 1 2 1000
set
set会对元素排序。
set不允许存放重复元素,插入重复元素不会报错,只是插入时返回的pair的second标志会是false。
set也没有重载中括号运算符,所以不能用角标访问元素。
set有迭代器。
#include <iostream>
using namespace std;
// 先导入头文件
#include <set>
int main(){
// 也可声明为 set<int, less<int>> s; 这里也用到了谓词
set<int> s;
s.insert(3);
s.insert(100);
s.insert(-99);
s.insert(1);
const pair<set<int>::iterator, bool> p = s.insert(3);
if(p.second)
{
cout << "重复插入成功" << endl;
}else{
cout << "重复插入失败" << endl;
}
for(auto it = s.begin(); it != s.end(); it ++)
{
cout << *it << " ";
}
cout << endl;
return 0;
}
输出:
重复插入失败
-99 1 3 100
谓词
谓词就是一个判断式,是一个返回值是bool的函数。
当有排序功能的容器中存放的是自定义类对象时,就需要自定义谓词,否则运行时会出错。
这里以set为例展示自定义谓词,priority_queue类似。
#include <iostream>
using namespace std;
// 先导入头文件
#include <set>
// 自定义类
class Student{
public:
string name;
int age;
Student(string name, int age){
this->name = name;
this->age = age;
}
// 重载<<运算符,使Student对象能够被标准输出流打印
friend const ostream & operator << (const ostream & out, const Student & stu)
{
cout << "name = " << stu.name << ", age = " << stu.age << endl;
return out;
}
};
// 自定义谓词
struct CustomCompare{
bool operator()(const Student& s1, const Student& s2) const{
return s1.age < s2.age;
}
};
int main(){
set<Student, CustomCompare> s;
s.insert(Student("张三", 32));
s.insert(Student("王五", 18));
s.insert(Student("李四", 30));
for(auto it = s.begin(); it != s.end(); it ++){
cout << *it;
}
return 0;
}
输出:
name = 王五, age = 18
name = 李四, age = 30
name = 张三, age = 32