C++基础知识【9】STL

C++STL包括了容器(如vector、deque、list、set、map和multimap)、算法(如find、sort和transform)和迭代器。容器提供了数据存储和管理的方式,其中序列式容器支持随机访问,关联式容器按键值排序。算法是通用的函数模板,适用于不同容器,如find用于查找,sort用于排序,transform用于元素变换。迭代器作为访问容器元素的抽象指针,支持各种操作。
摘要由CSDN通过智能技术生成

目录

一、概述

二、容器

2.1 序列式容器

2.1.1、vector

2.1.2、deque

2.1.3、list

2.2、关联式容器

2.2.1、set

2.2.2、map

2.2.3、multimap

2.3、容器适配器

2.3.1、stack

2.3.2、queue

三、算法

3.1、find()

3.2、sort

3.3、transform

四、迭代器


一、概述

        C++ STL是指标准模板库(Standard Template Library),它是一个由函数模板和类模板组成的C++库。STL提供了大量的通用数据结构和算法,以方便程序员快速开发高质量的程序。

        STL由三个部分组成:容器(Containers)、算法(Algorithms)和迭代器(Iterators)。

二、容器

        容器是STL的核心部分,它提供了一种管理和存储数据的方式。C++ STL中的容器可分为三类:序列式容器(Sequence Containers)、关联式容器(Associative Containers)和容器适配器(Container Adaptors)。

2.1 序列式容器

序列式容器是按照线性顺序存储数据的容器,其中最常用的是vector、deque和list。

2.1.1、vector

        vector是一个可变大小的数组,支持随机访问,即可以通过下标访问其中的元素。vector是一个高效的容器,其尾部添加或删除元素的操作复杂度为O(1),但在中间或头部添加或删除元素的操作需要移动其他元素,其复杂度为O(n)。

下面是一个vector的例子:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> vec = {1, 2, 3, 4, 5};
    vec.push_back(6);
    for (int i = 0; i < vec.size(); ++i)
    {
        std::cout << vec[i] << " ";
    }
    return 0;
}

        vector是一个动态数组,可以随时增加和删除元素,支持随机访问。vector的优点是支持快速的随机访问,可以在尾部插入和删除元素。缺点是在中间插入或删除元素时,需要移动后面的元素,效率较低。vector适合于元素数量比较少,需要随机访问的情况。

2.1.2、deque

        deque是一个双端队列,可以在头部和尾部快速添加和删除元素,支持随机访问,但其随机访问的效率不如vector。

下面是一个deque的例子:

#include <iostream>
#include <deque>

int main()
{
    std::deque<int> deq = {1, 2, 3, 4, 5};
    deq.push_front(0);
    deq.push_back(6);
    for (int i = 0; i < deq.size(); ++i)
    {
        std::cout << deq[i] << " ";
    }
    return 0;
}

        deque的优点是既支持快速的随机访问,又支持在队列两端插入和删除元素。缺点是需要分配多个内存块来存储数据,对内存的使用比较浪费。deque适合于元素数量比较多,需要在队列两端插入和删除元素,同时需要随机访问元素的情况。

2.1.3、list

        list是一个双向链表,支持在任意位置进行常数时间的插入和删除操作,但不支持随机访问。

下面是一个list的例子:

#include <iostream>
#include <list>

int main()
{
    std::list<int> li = {1, 2, 3, 4, 5};
    li.push_front(0);
    li.push_back(6);
    for (auto it = li.begin(); it != li.end(); ++it)
    {
        std::cout << *it << " ";
    }
    return 0;
}

        list的优点是在任意位置插入和删除元素时,效率很高。缺点是不能通过下标访问元素,只能通过迭代器访问元素。list适合于元素数量比较多,需要频繁地在中间插入和删除元素的情况。

2.2、关联式容器

        关联式容器是按照键值(Key)排序存储数据的容器,其中最常用的是set和map。

2.2.1、set

        set是一个集合,其中元素按照某种顺序排列,并且每个元素都是唯一的。插入、删除和查找操作的复杂度均为O(logn)。

下面是一个set的例子:

#include <iostream>
#include <set>

int main()
{
    std::set<int> s = {1, 2, 3, 4, 5};
    s.insert(6);
    for (auto it = s.begin(); it != s.end(); ++it)
    {
        std::cout << *it << " ";
    }
    return 0;
}

        set的优点是可以快速地插入、删除和查找元素,并且元素是按照一定的顺序排列的。缺点是不能通过下标访问元素。set适合于需要按照一定的顺序存储元素,并且需要快速地插入、删除和查找元素的情况。

2.2.2、map

        map是一个键值对的容器,每个键对应一个值,其中元素是由键值对(Key-Value Pair)组成的。插入、删除和查找操作的复杂度均为O(logn)。

下面是一个map的例子:

#include <iostream>
#include <map>

int main()
{
    std::map<std::string, int> m = {{"apple", 1}, {"banana", 2}, {"orange", 3}};
    m["watermelon"] = 4;
    for (auto it = m.begin(); it != m.end(); ++it)
    {
        std::cout << it->first << ":" << it->second << " ";
    }
    return 0;
}

        map的优点是可以快速地按照键进行查找、插入和删除操作。缺点是不能通过下标访问元素。map适合于需要存储键值对,并且需要快速地按照键进行查找、插入和删除操作的情况

2.2.3、multimap

multimap是一个键值对的容器,每个键可以对应多个值,可以快速地进行查找、插入和删除元素。

下面是一个multimap的例子:

#include <iostream>
#include <map>

int main()
{
    std::multimap<std::string, int> m = {{"apple", 1}, {"banana", 2}, {"orange", 3}, {"apple", 4}};
    m.insert(std::make_pair("apple", 5));
    for (auto it = m.begin(); it != m.end(); ++it)
    {
        std::cout << it->first << ":" << it->second << " ";
    }
    return 0;
}

2.3、容器适配器

        容器适配器是一种特殊的容器,它们使用不同的数据结构来实现STL中的标准容器接口。常用的容器适配器有stack和queue。

2.3.1、stack

        stack是一种后进先出(Last-In-First-Out,LIFO)的数据结构,可以使用vector或deque来实现。

下面是一个stack的例子:

#include <iostream>
#include <stack>

int main()
{
    std::stack<int, std::vector<int>> s;
    s.push(1);
    s.push(2);
    s.push(3);
    while (!s.empty())
    {
        std::cout << s.top() << " ";
        s.pop();
    }
    return 0;
}

2.3.2、queue

        queue是一种先进先出(First-In-First-Out,FIFO)的数据结构,可以使用deque来实现。

下面是一个queue的例子:

#include <iostream>
#include <queue>

int main()
{
    std::queue<int, std::deque<int>> q;
    q.push(1);
    q.push(2);
    q.push(3);
    while (!q.empty())
    {
        std::cout << q.top() << " ";
    q.pop();
    }
    return 0;
}

三、算法

        STL中的算法是一个模板函数库,包括了大量的常用算法,如查找、排序、合并、查找、遍历等等。STL中的算法不依赖于具体的容器类型,因此可以在不同的容器中使用相同的算法函数。

        STL中的算法函数都位于algorithm头文件中,可以通过#include <algorithm>来引用。

3.1、find()

        查找算法,用于在容器中查找指定的元素,返回指向该元素的迭代器,如果没有找到则返回容器尾后迭代器。

下面是一个find的例子:

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> v = {1, 2, 3, 4, 5};
    auto it = std::find(v.begin(), v.end(), 3);
    if (it != v.end())
    {
        std::cout << "found " << *it << std::endl;
    }
    else
    {
        std::cout << "not found" << std::endl;
    }
    return 0;
}

3.2、sort

        排序算法,用于对容器中的元素进行排序,默认按照升序排序,也可以指定排序方式。

下面是一个sort的例子:

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> v = {5, 3, 1, 4, 2};
    std::sort(v.begin(), v.end());
    for (auto it = v.begin(); it != v.end(); ++it)
    {
        std::cout << *it << " ";
    }
    return 0;
}

3.3、transform

        变换算法,用于对容器中的元素进行变换,可以将一个容器的元素复制到另一个容器中,并对其进行变换操作。

下面是一个transform的例子:

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> v = {1, 2, 3, 4, 5};
    std::vector<int> v2;
    std::transform(v.begin(), v.end(), std::back_inserter(v2), [](int x) { return x * x; });
    for (auto it = v2.begin(); it != v2.end(); ++it)
    {
        std::cout << *it << " ";
    }
    return 0;
}

另外还有一些常用的算法函数:

  1. reverse():对一个区间中的元素进行反转。

  2. accumulate():对一个区间中的元素进行累加。

  3. unique():在一个区间中删除相邻的重复元素。

  4. count():统计一个区间中指定值的元素个数。

  5. merge():将两个已排序的区间合并成一个已排序的区间。

四、迭代器

        迭代器是STL中的一个重要概念,它是一种通用的、抽象的指针类型,用于访问容器中的元素。通过使用迭代器,可以遍历容器中的元素,实现各种算法和操作。

        STL中提供了五种迭代器类型:输入迭代器(Input Iterator)、输出迭代器(Output Iterator)、正向迭代器(Forward Iterator)、双向迭代器(Bidirectional Iterator)和随机访问迭代器(Random Access Iterator)。

        stack和queue不支持迭代器

下面是一些常用的迭代器函数:

  1. begin():返回容器的起始位置的迭代器。

  2. end():返回容器的结束位置的迭代器。

  3. advance():使迭代器向前或向后移动指定的距离。

  4. distance():计算两个迭代器之间的距离。

  5. next():返回迭代器的下一个位置的迭代器。

  6. prev():返回迭代器的前一个位置的迭代器。

下面是一个迭代器的例子:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v = {1, 2, 3, 4, 5};
    for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        std::cout << *it << " ";
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从此不归路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值