美文网首页
C++高级之SLT中的容器与函数谓词

C++高级之SLT中的容器与函数谓词

作者: 大虾啊啊啊 | 来源:发表于2022-08-06 11:28 被阅读0次

一、前言

STL 是“Standard Template Library”的缩写,中文译为“标准模板库”。STL 是 C++ 标准库的一部分,不用单独安装。

二、STL 中的容器

1、 vector

向量容器,(内部:封装动态大小数组作为容器,能够存放任意的动态数组)

#include <iostream>

#include <vector>

using namespace std;

int main() {
    vector<int> v1;
    //指定10个大小的空间
    vector<int> v2(10);
    //指定5个大小空间,默认值都是1
    vector<int> v3(5, 1);
    vector<int> v4;

    //插入数据
    //前面插入
    v4.insert(v4.begin(), 2);
    v4.insert(v4.begin(), 3);
    v4.insert(v4.begin(), 6);
    //后面插入
    v4.insert(v4.end(), 5);
    cout << "第一个值是:" << v4.front() << endl;
    //修改第一个
    v4.front() = 99;
    cout << "修改后第一个值是:" << v4.front() << endl;
    //代表操作最后一个
    //v4.back();
    //移除 第一个元素(内部通过迭代器移除)
    v4.erase(v4.begin());
    //移除之后遍历,使用迭代器
    //vector<int>::iterator it 使用auto类型推导,和kotlin一样
    for (auto it = v4.begin(); it != v4.end(); it++) {
        //迭代器中,其实就是指针位移操作 it代表指针
        cout << "当前的值:" << *it << endl;

    }


    return 0;
}
第一个值是:6
修改后第一个值是:99
当前的值:3
当前的值:2
当前的值:5

2、stack

栈、先进后出的数据结构

  stack<int> stack;
    //压栈(注意无法压到指定的位置)
    stack.push(2);
    stack.push(3);
    stack.push(6);
    stack.push(7);

    //遍历、弹栈
    while (!stack.empty()) {
        //获取栈顶元素
        int top = stack.top();
        cout << "当前元素" << top << endl;
        //弹栈
        stack.pop();
    }
    cout << "弹完之后:" << stack.empty() << endl;
当前元素7
当前元素6
当前元素3
当前元素2
弹完之后:1

3、queue

队列(内部:基本上 链表 、 数组 ),先进先出的是数据结构,FIFO 原则

    queue<int> q;
    q.push(6);
    q.push(3);
    q.push(4);
    q.push(7);
    cout<<"修改前第一个值是:"<<q.front()<<endl;
    q.front() = 999;
    cout<<"修改后第一个值是:"<<q.front()<<endl;
    //遍历
    while (!q.empty()){
        int value = q.front();
        cout<<"当前的值:"<<value<<endl;
        //弹出去
        q.pop();
    }
    cout<<"遍历完之后:"<<q.empty()<<endl;
修改前第一个值是:6
修改后第一个值是:999
当前的值:999
当前的值:3
当前的值:4
当前的值:7
遍历完之后:1

4、priority_queue

优先级队列,在上面我们知道队列是先进先出的数据结构、那么优先级队列也就是对队列进行排序的队列。


    //隐士代码
    //   priority_queue<int,vector<int>,less<int>> p;
    priority_queue<int> p;
    p.push(4);
    p.push(7);
    p.push(4);
    p.push(9);
    p.push(999);
    //遍历
    while (!p.empty()) {
        int value = p.top();
        cout << "当前的值:" << value << endl;
        //弹出去
        p.pop();
    }

当前的值:999
当前的值:9
当前的值:7
当前的值:4
当前的值:4

结果是默认从大到小的排序。我们看到priority_queue的源码中指定了三个模板函数。

    //隐士代码
  priority_queue<int,vector<int>,less<int>> p;
  template<typename _Tp>
    struct less : public binary_function<_Tp, _Tp, bool>
    {
      _GLIBCXX14_CONSTEXPR
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x < __y; }
    };

内部通过比较大小实现排序。当我们想从小到大排序我们可以这样,指定模板greater

//隐士代码
     priority_queue<int,vector<int>,greater<int>> p;
    //priority_queue<int> p;
    p.push(4);
    p.push(7);
    p.push(8);
    p.push(9);
    p.push(999);
    //遍历
    while (!p.empty()) {
        int value = p.top();
        cout << "当前的值:" << value << endl;
        //弹出去
        p.pop();
    }
当前的值:4
当前的值:7
当前的值:8
当前的值:9
当前的值:999

而我们再看看greater的内部实现,其实也是通过比较大小实现。

  template<typename _Tp>
    struct greater : public binary_function<_Tp, _Tp, bool>
    {
      _GLIBCXX14_CONSTEXPR
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x > __y; }
    };

5、list

Java:ArrayList采用Object[]数组, C++的list 内部:采用链表

    list<int> l;
    //插入到前面
    l.push_front(50);
    //插入到后面
    l.push_back(166);
    //修改第一个
    l.front() = 999;

    //遍历
    for (auto it = l.begin(); it != l.end(); it++) {
        cout<<*it<<endl;
    }
999
166

6、set

(内部:红黑树结构),会对你存入的数据进行排序,但是绝对不允许元素相同

    //从大到小排序 greater
    set<int,greater<int>> s1;
    s1.insert(100);
    s1.insert(200);
    s1.insert(6);
    s1.insert(400);
    for(auto it =s1.begin();it!=s1.end();it++){
        cout<<*it<<endl;
    }
    cout<<"-------------------"<<endl;
    //从小到大排序 less
    set<int,less<int>> s2;
    s2.insert(100);
    s2.insert(200);
    s2.insert(6);
    s2.insert(400);
    //不能重复
    s2.insert(400);
    for(auto it =s2.begin();it!=s2.end();it++){
        cout<<*it<<endl;
    }

400
200
100
6
-------------------
6
100
200
400

7、谓词

前面我们使用set的时候带有排序功能,因为我们存的数据是int类型,底层通过比较大小来实现,如果我们存的是对象呢?我们可以自定义谓词来实现排序。也就是我们可以根据自定义比较器来进行排序。

class Student {
public:
    int age;
    string name;

    Student(int age, string name) {
        this->age = age;
        this->name = name;
    }

};

/**
 * 使用谓词,自定义比较器(抄源码)
 */
struct myless : public binary_function<Student, Student, bool> {
    _GLIBCXX14_CONSTEXPR
    bool
    operator()(const Student &s1, const Student &s2) const { return s1.age < s2.age; }
};

int main() {
    set<Student, myless> studentSets;
    Student s1(15, "小明");
    Student s2(330, "小红");
    Student s3(5, "小花");
    Student s4(19, "小狗");
    studentSets.insert(s1);
    studentSets.insert(s2);
    studentSets.insert(s3);
    studentSets.insert(s4);

    for (auto it = studentSets.begin(); it != studentSets.end(); it++) {
        cout << it->name << it->age << endl;
    }

}
小花5
小明15
小狗19
小红330

相关文章

网友评论

      本文标题:C++高级之SLT中的容器与函数谓词

      本文链接:https://www.haomeiwen.com/subject/kmgmwrtx.html