hwaityd的小窝

Loading...

标准模板库(STL)

1. 六大组件

容器(Containers)

  • 用于存储和管理数据集合的数据结构,如vectorlistmap等。
  • 提供了数据的组织、访问和修改的方法。

迭代器(Iterators)

  • 用于遍历容器中的元素。
  • 迭代器是一个类,它封装了指针,并提供类似指针的行为。

算法(Algorithms)

  • 提供了一系列通用的算法,如排序、搜索、变换等。
  • 算法通常接受迭代器作为参数,使其可以操作各种容器。

仿函数(Functors)

  • 是可以像函数一样使用的类的实例。
  • 它们通常重载了函数调用操作符operator()

适配器(Adapters)

  • 用于修改容器、迭代器或函数的行为。
  • 包括迭代器适配器、函数适配器等。

空间配置器(Allocators)

  • 用于管理动态内存的分配和释放。
  • 控制容器内部如何分配和释放内存。

2. 容器及使用

容器是STL中用于存储数据的组件,它们提供了一系列的模板类,用于存储和管理数据集合。容器可以分为序列容器(如vectordequelistarray)、关联容器(如setmap)、容器适配器(如stackqueuepriority_queue)等。

  • 用法:容器通常提供构造函数、迭代器、成员函数(如size()empty()push_back()等)来管理数据。

3. 迭代器

迭代器是STL中用于遍历容器元素的工具。迭代器可以指向容器中的某个元素,支持前进、后退、元素访问等操作。

  • 用法:通过调用容器的begin()end()成员函数获取迭代器,然后使用循环结构遍历容器。

4. 空间配置器及其使用

空间配置器负责容器内部的内存分配和释放。STL提供了默认的空间配置器allocator,也可以自定义空间配置器。

  • 用法:通过调用空间配置器的allocate()deallocate()成员函数来分配和释放内存。容器构造时可以指定使用的空间配置器。

5. 算法

STL提供了大量的算法,这些算法可以对容器中的元素进行操作,如排序、搜索、变换等。

  • 用法:直接调用STL算法,并将容器的迭代器作为参数传递。例如,使用sort()算法对vector进行排序。

6. 仿函数

仿函数是一类特殊的对象,它们重载了函数调用操作符,可以像函数一样被调用。

  • 用法:创建仿函数对象,并像调用函数一样使用它们。例如,使用plus<int>()来计算两个整数的和。

7. 适配器

适配器是一种修改已有组件行为的工具,包括迭代器适配器、函数适配器等。

  • 用法:使用适配器来改变迭代器的行为,或者将函数或仿函数转换成另一种形式。例如,使用bind来绑定函数的某些参数,或者使用mem_fn来调用类的成员函数。

容器实现

由于要求每个容器都展示多种操作,我会为每个容器编写一个示例代码,展示它们的常用操作。为了简化代码,我将在代码中省略std::前缀,并在开头声明命名空间using namespace std;

1. 序列式容器

vector

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};

    // 插入
    vec.insert(vec.begin() + 2, 6); // 在索引2的位置插入6

    // 删除
    vec.erase(vec.begin() + 2); // 删除索引2的元素

    // 修改
    vec[2] = 10; // 修改索引2的元素为10

    // 判断是否为空
    bool isEmpty = vec.empty() ? true : false;

    // 查找
    auto it = find(vec.begin(), vec.end(), 4);

    // 排序
    sort(vec.begin(), vec.end());

    // 逆序
    reverse(vec.begin(), vec.end());

    // 清空
    clear(vec);

    // 迭代器操作
    for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

deque

#include <iostream>
#include <deque>

using namespace std;

int main() {
    deque<int> deq = {1, 2, 3, 4, 5};

    // 插入
    deq.push_back(6);
    deq.push_front(0);

    // 删除
    deq.pop_back();
    deq.pop_front();

    // 修改
    deq[2] = 10;

    // 判断是否为空
    bool isEmpty = deq.empty() ? true : false;

    // 查找
    it = find(deq.begin(), deq.end(), 4);

    // 迭代器操作
    for (auto it = deq.rbegin(); it != deq.rend(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

list

#include <iostream>
#include <list>

using namespace std;

int main() {
    list<int> lst = {1, 2, 3, 4, 5};

    // 插入
    lst.insert(lst.begin(), 0);
    lst.insert(++lst.begin(), 6);

    // 删除
    lst.erase(++lst.begin()); // 删除第二个元素

    // 修改
    *(++lst.begin()) = 10; // 修改第二个元素为10

    // 判断是否为空
    bool isEmpty = lst.empty() ? true : false;

    // 查找
    auto it = find(lst.begin(), lst.end(), 4);

    // 迭代器操作
    for (auto it = lst.rbegin(); it != lst.rend(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

2. 关联式容器

set

#include <iostream>
#include <set>

using namespace std;

int main() {
    set<int> s = {1, 2, 3, 4, 5};

    // 插入
    s.insert(6);

    // 删除
    s.erase(3);

    // 修改
    // Set不提供直接修改元素的接口,需要删除后重新插入

    // 判断是否为空
    bool isEmpty = s.empty() ? true : false;

    // 查找
    auto it = s.find(4);

    // 迭代器操作
    for (auto it = s.rbegin(); it != s.rend(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

multiset

#include <iostream>
#include <set>

using namespace std;

int main() {
    multiset<int> ms = {1, 2, 2, 3, 4};

    // 插入
    ms.insert(5);

    // 删除
    ms.erase(ms.find(2)); // 删除一个2

    // 判断是否为空
    bool isEmpty = ms.empty() ? true : false;

    // 查找
    auto it = find(ms.begin(), ms.end(), 4);

    // 迭代器操作
    for (auto it = ms.rbegin(); it != ms.rend(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

map

#include <iostream>
#include <map>

using namespace std;

int main() {
    map<int, string> mp = {{1, "one"}, {2, "two"}, {3, "three"}};

    // 插入
    mp.insert({4, "four"});

    // 删除
    mp.erase(2);

    // 修改
    mp[3] = "three modified";

    // 判断是否为空
    bool isEmpty = mp.empty() ? true : false;

    // 查找
    auto it = mp.find(3);

    // 迭代器操作
    for (auto it = mp.rbegin(); it != mp.rend(); ++it) {
        cout << it->first << ": " << it->second << " ";
    }
    cout << endl;

    return 0;
}

multimap

#include <iostream>
#include <map>

using namespace std;

int main() {
    multimap<int, string> mmp = {{1, "one"}, {2, "two"}, {2, "two again"}};

    // 插入
    mmp.insert({3, "three"});

    // 删除
    mmp.erase(2); // 删除所有键为2的元素

    // 判断是否为空
    bool isEmpty = mmp.empty() ? true : false;

    // 查找
    auto range = mmp.equal_range(2);

    // 迭代器操作
    for (auto it = range.first; it != range.second; ++it) {
        cout << it->first << ": " << it->second << " ";
    }
    cout << endl;

    return 0;
}

请注意,这些示例代码展示了每个容器的基本操作,包括插入、删除、修改(如果支持)、查找、判断是否为空、迭代器操作和打印。由于setmap是有序容器,它们的元素会自动排序。multisetmultimap允许重复的元素。在实际使用中,你可能需要根据具体需求调整这些操作。

posted on 2024-10-20 00:56  hwaityd  阅读(3)  评论(0编辑  收藏  举报