
注:编码工具是CLion+Cygwin64
目录
STL概念
vector
初始化
添加元素
访问元素
修改元素
删除元素
遍历元素
stack
queue
priority_queue
list
set
谓词
全称Standard Template Library,标准模板库,类似于Java的集合框架。
与Java的集合框架不同的是,Java集合框架把集合的所有功能全部封装在集合类中,而C++则把功能拆分到STL包、算法包和迭代器中。
STL下有vector、queue、priority_queue、list、set等容器,全部定义在std命名空间中,如果没有using namespace std声明,则需要以std::vector这样的形式使用。
所有容器均使用了模板,使用时需要指定具体类型。
所有容器均需要导入相应的头文件。
#includeusing namespace std; // 要先导入头文件 #include int main(){ vector v;// 默认初始化大小 vector v2(10);// 初始化大小为10 vector v3(10, 0);// 初始化大小为10,元素全部初始化为0 return 0; }
#includeusing namespace std; #include int main(){ vector 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
#includeusing namespace std; #include int main(){ vector 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
#includeusing namespace std; #include int main(){ vector 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
#includeusing namespace std; #include int main(){ vector v; v.push_back(1); v.push_back(2); v.push_back(3); // 删除元素,通过迭代器 v.erase(v.begin()); cout << *v.begin() << endl; return 0; }
输出:
2
#includeusing namespace std; #include int main(){ vector 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 ::iterator it = v.begin(); it != v.end(); it ++) { cout << *it << " "; } cout << endl; return 0; }
输出:
1 10 100 1 10 100
栈的特点:元素后进先出,Last In First Out,LIFO。
stack没有迭代器,也不能用角标访问元素。
#includeusing namespace std; // 先导入头文件 #include int main(){ stack 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
队列的特点:元素先进先出,First In First Out, FIFO。
queue也没有迭代器,也不能用角标访问元素。
queue的方法和stack类似。
#includeusing namespace std; // 先导入头文件 #include int main(){ queue 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
优先级队列,会对元素进行排序。其他特性和queue一样,函数和stack类似。
#includeusing namespace std; // 先导入头文件 #include int main(){ // 也可声明为 priority_queue , less > pq; // 上面的less是一个结构体,里面定义了一个函数,重载了圆括号运算符,返回值是bool,这种函数称为谓词 priority_queue pq; // 入队元素 pq.push(1); pq.push(-1); pq.push(2); // 遍历 for(;!pq.empty();) { cout << pq.top() << " "; // 出队队首元素 pq.pop(); } cout << endl; // 元素从小到大排列 priority_queue , greater > 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有迭代器,但是没有重载中括号运算符,所以不能用角标访问元素。
#includeusing namespace std; // 先导入头文件 #include int main(){ list
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不允许存放重复元素,插入重复元素不会报错,只是插入时返回的pair的second标志会是false。
set也没有重载中括号运算符,所以不能用角标访问元素。
set有迭代器。
#includeusing namespace std; // 先导入头文件 #include int main(){ // 也可声明为 set > s; 这里也用到了谓词 set s; s.insert(3); s.insert(100); s.insert(-99); s.insert(1); const pair ::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类似。
#includeusing namespace std; // 先导入头文件 #include // 自定义类 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 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