C++学习笔记——(七)STL(Standard Template Library)与函数谓词

注:编码工具是CLion+Cygwin64

目录

STL概念

vector

初始化

添加元素

访问元素

修改元素

删除元素

遍历元素

stack

queue

priority_queue

list

set

谓词


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值