STL标准模板库

STL 概念

STL(标准模板库)是C++标准库的重要组成部分,它提供了一系列常用的数据结构和算法,极大地丰富了C++的功能。STL主要包含以下几个部分:

一、容器(Containers)

STL提供了多种容器,每种容器都有其特定的用途和性能特征。常见的容器包括:

  1. vector:动态数组,支持快速随机访问和尾部插入删除。
  2. deque:双端队列,支持快速随机访问和两端插入删除。
  3. list:双向链表,支持双向遍历和任意位置插入删除。
  4. forward_list:单向链表,支持单向遍历和任意位置插入删除。
  5. set:有序集合,元素唯一且自动排序。
  6. multiset:有序多重集合,元素可以重复且自动排序。
  7. map:有序映射,键值对集合,键唯一且自动排序。
  8. multimap:有序多重映射,键可以重复且自动排序。
  9. unordered_set:无序集合,元素唯一,无序存储。
  10. unordered_multiset:无序多重集合,元素可以重复,无序存储。
  11. unordered_map:无序映射,键值对集合,键唯一,无序存储。
  12. unordered_multimap:无序多重映射,键可以重复,无序存储。

此外,STL还提供了基于容器的适配器,如栈(stack)、队列(queue)和优先队列(priority_queue),它们分别基于deque、list或vector等容器实现。

二、迭代器(Iterators)

迭代器是一种广义指针,提供了对容器和容器元素的通用访问方法。STL中的算法通过迭代器来操作容器,将算法与特定容器的实现解耦。迭代器分为以下几类:

  1. 输入迭代器:只读访问容器中的元素,支持单向遍历。
  2. 输出迭代器:只能写入元素,不能读取,支持单向遍历。
  3. 前向迭代器:支持只读或读写访问,支持单向遍历,允许多次遍历相同的元素。
  4. 双向迭代器:支持双向遍历,既可以向前遍历,也可以向后遍历。
  5. 随机访问迭代器:支持随机访问,可以直接跳转到容器中的任意元素,是功能最强的迭代器类型。

三、算法(Algorithms)

STL提供了大量的算法,涵盖了排序、搜索、数值操作、生成和修改序列等常见任务。这些算法可以直接应用于容器,也可以通过迭代器应用于数组或其他数据结构。常见的算法包括:

  1. 查找和排序:如find、count、sort、binary_search、merge等。
  2. 修改和操作:如copy、transform、replace、fill、swap、reverse等。
  3. 数值操作:如accumulate、inner_product、partial_sum、adjacent_difference等。

四、函数对象(Function Objects)

函数对象(Functors)是可以像函数一样调用的对象,它们可以作为算法的参数传递,用于自定义操作。STL提供了多个内置的函数对象,如比较器(less、greater)、算术操作(plus、minus)、逻辑操作(logical_and、logical_or)等。

五、适配器(Adapters)

适配器提供了对现有组件的重新包装,使其能够符合不同的接口需求。STL中常见的适配器包括容器适配器(如stack、queue、priority_queue)和迭代器适配器(如reverse_iterator)。

综上所述,STL是一个功能强大且灵活的库,它提供了丰富的数据结构和算法,使得C++程序员能够更加方便地编写高效、可重用的代码。


STL详细功能表示

STL(Standard Template Library,标准模板库)是C++的一个重要组成部分,提供了许多常用的数据结构和算法。以下是一些STL中常用的操作,涵盖了容器、迭代器和算法等方面:

一、容器常用操作

1. vector(向量)

  • 声明vector<int> vec;vector<int> vec(100, 2);(声明含有100个元素,初值为2的int型vector对象)
  • 插入vec.push_back(1); 在向量末尾插入元素。vec.insert(vec.begin()+i, 1); 在指定位置插入元素。
  • 删除vec.erase(vec.begin()+2); 删除指定位置的元素。vec.erase(vec.begin()+i, vec.begin()+j); 删除区间内的元素。
  • 访问vec[i]; 使用下标访问元素。或使用迭代器访问。
  • 其他vec.size(); 求向量大小。vec.clear(); 清空向量。vec.empty(); 判断向量是否为空。

2. deque(双端队列)

  • 插入push_back(elem); 在容器尾部添加一个数据。push_front(elem); 在容器头部插入一个数据。
  • 删除pop_back(elem); 在容器尾部删除一个数据。pop_front(elem); 在容器头部删除一个数据。
  • 其他:与vector类似,支持inserterasesizeempty等操作。

3. set(集合)

  • 插入insert(elem); 插入元素。
  • 查找find(elem); 查找元素。
  • 删除remove(elem); 删除元素。
  • 其他count(elem); 统计元素出现的次数(set中只有0和1两种可能)。set::iterator 迭代器用于遍历集合。

4. map(映射)

  • 插入insert(pair<K, V>); 插入键值对。或使用m[key] = value;的方式插入。
  • 查找find(key); 查找键对应的值。
  • 删除remove(key); 删除键对应的键值对。
  • 其他count(key); 统计键出现的次数(map中只有0和1两种可能)。map::iterator 迭代器用于遍历映射。

5. stack(栈)

  • 插入push(elem); 在栈顶插入元素。
  • 删除pop(); 删除栈顶元素。
  • 访问top(); 获取栈顶元素的值。
  • 其他size(); 求栈的大小。empty(); 判断栈是否为空。

6. queue(队列)

  • 插入push(elem); 在队尾插入元素。
  • 删除pop(); 删除队头元素。
  • 访问front(); 获取队头元素的值。back(); 获取队尾元素的值。
  • 其他size(); 求队列大小。empty(); 判断队列是否为空。

7. priority_queue(优先队列)

  • 插入push(elem); 在堆内插入元素且仍保持堆的结构。
  • 删除pop(); 弹出堆顶元素。
  • 访问top(); 获取堆顶元素的值。
  • 其他:可以通过指定比较函数或仿函数来改变元素的优先级顺序。

二、迭代器常用操作

  • 迭代器类型:包括输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器。
  • 基本操作++it;it++; 使迭代器指向下一个元素。--it;it--;(仅双向和随机访问迭代器支持)使迭代器指向前一个元素。*it; 解引用迭代器,获取其指向的元素的值。
  • 高级操作std::advance(it, n); 将迭代器向前移动n个位置。std::prev(it); 获取迭代器的前一个位置(仅双向和随机访问迭代器支持)。std::next(it); 获取迭代器的下一个位置。

三、算法常用操作

  • 排序sort(a.begin(), a.end()); 对容器中的元素进行排序。
  • 查找find(a.begin(), a.end(), value); 在容器中查找等于value的元素。
  • 搜索search(a.begin(), a.end(), b.begin(), b.end()); 在容器a中查找子序列b。
  • 替换replace(a.begin(), a.end(), value1, value2); 将容器中等于value1的元素替换为value2。
  • 数值算法:如equalincludesmax_elementmin_element等,用于比较和查找容器中的元素。

四、其他常用操作

  • 字符串操作:如str.insert(pos, "abc"); 在字符串中插入子串。str.erase(pos, n); 删除字符串中的部分字符。str.find('A'); 查找字符在字符串中的位置。
  • 内存操作:如memset(f, -1, sizeof(f)); 将某一块内存全部填充为指定的值。

以上只是STL中常用操作的一部分,STL还提供了许多其他功能强大的数据结构和算法,可以根据具体需求进行选择和使用。


map容器

在C++的标准模板库(STL)中,map 是一种关联容器,它存储的是键值对(key-value pairs),其中每个键(key)都是唯一的,并且与一个值(value)相关联。map 容器内部通常通过红黑树(一种自平衡二叉搜索树)来实现,这意味着它具有对数时间复杂度的查找、插入和删除操作。

map 的键和值可以是任何可以复制的类型,但键类型必须支持 < 运算符来进行比较,以便 map 能够根据键的顺序来组织数据。默认情况下,map 是按键的升序排列的。

以下是一些 map 的基本用法示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <map>
#include <string>

int main() {
// 创建一个空的 map,键是 std::string 类型,值是 int 类型
std::map<std::string, int> myMap;

// 插入键值对
myMap["one"] = 1;
myMap["two"] = 2;
myMap["three"] = 3;

// 访问元素
std::cout << "The number for 'one' is " << myMap["one"] << std::endl;

// 遍历 map
for (const auto& pair : myMap) {
std::cout << pair.first << " => " << pair.second << std::endl;
}

// 查找元素
auto it = myMap.find("two");
if (it != myMap.end()) {
std::cout << "Found 'two' with value " << it->second << std::endl;
} else {
std::cout << "'two' not found in map" << std::endl;
}

// 删除元素
myMap.erase("three");

// 检查元素是否存在(另一种方式)
if (myMap.count("one") > 0) {
std::cout << "'one' exists in map" << std::endl;
}

// 获取 map 的大小
std::cout << "Size of map: " << myMap.size() << std::endl;

return 0;
}

在这个示例中,我们创建了一个 std::map<std::string, int> 类型的 myMap,然后插入了一些键值对。我们使用下标运算符 [] 来访问和修改元素,使用范围 for 循环来遍历整个 map,使用 find 方法来查找元素,使用 erase 方法来删除元素,以及使用 count 方法来检查元素是否存在。最后,我们使用 size 方法来获取 map 的大小。

请注意,当使用下标运算符 [] 访问 map 中的元素时,如果键不存在,map 会自动创建一个新的键值对,并将值初始化为默认值(对于基本类型,如 int,默认值是 0)。如果你不想在键不存在时创建新的键值对,应该使用 find 方法来检查键是否存在。


string字符串

下面是一些关于C++标准模板库(STL)中std::string类的常用函数笔记。std::string类是用于表示和操作字符串的类,提供了丰富的成员函数来进行字符串的创建、访问、修改、查询等操作。

1. 构造函数

  • 默认构造函数

    1
    std::string str; // 创建一个空字符串
  • 用C风格字符串构造

    1
    std::string str("Hello, World!"); // 使用C风格字符串初始化
  • 用字符数组和长度构造

    1
    2
    char c_str[] = "Hello";
    std::string str(c_str, 5); // 使用字符数组的前5个字符初始化
  • 用单个字符重复n次构造

    1
    std::string str(5, 'a'); // 创建一个字符串 "aaaaa"
  • 用另一个std::string对象构造

    1
    2
    std::string str1("Hello");
    std::string str2(str1); // 使用str1初始化str2

2. 访问与修改

  • 访问单个字符

    1
    2
    char ch = str[0]; // 访问第一个字符
    str[0] = 'h'; // 修改第一个字符
  • 获取字符串的C风格表示

    1
    const char* c_str = str.c_str(); // 获取C风格字符串(以null结尾)
  • 字符串拼接

    1
    2
    str += " World!"; // 追加字符串
    str.append(" C++"); // 使用append函数追加字符串
  • 替换子字符串

    1
    str.replace(0, 5, "Hi"); // 将前5个字符替换为"Hi"
  • 插入子字符串

    1
    str.insert(5, " Inserted"); // 在索引5处插入字符串
  • 删除子字符串

    1
    str.erase(5, 6); // 删除从索引5开始的6个字符

3. 查询

  • 获取字符串长度

    1
    size_t len = str.length(); // 获取字符串长度
  • 检查是否为空

    1
    bool isEmpty = str.empty(); // 检查字符串是否为空
  • 查找子字符串

    1
    size_t pos = str.find("World"); // 查找子字符串位置
  • 子字符串查找(从指定位置开始)

    1
    size_t pos = str.find("World", 6); // 从索引6开始查找子字符串位置
  • 查找字符

    1
    size_t pos = str.find('o'); // 查找字符位置
  • 反向查找

    1
    size_t rpos = str.rfind("World"); // 反向查找子字符串位置

4. 字符串比较

  • 相等比较

    1
    bool isEqual = (str1 == str2); // 比较两个字符串是否相等
  • 不等比较

    1
    bool isNotEqual = (str1 != str2); // 比较两个字符串是否不等
  • 小于比较

    1
    bool isLess = (str1 < str2); // 比较两个字符串是否str1小于str2
  • 大于比较

    1
    bool isGreater = (str1 > str2); // 比较两个字符串是否str1大于str2
  • 子字符串比较

    1
    int cmp = str.compare(0, 5, "Hello"); // 比较子字符串

5. 其他常用函数

  • 转换为大写

    1
    std::transform(str.begin(), str.end(), str.begin(), ::toupper); // 需要包含<algorithm>和<cctype>
  • 转换为小写

    1
    std::transform(str.begin(), str.end(), str.begin(), ::tolower); // 需要包含<algorithm>和<cctype>
  • 交换两个字符串

    1
    std::swap(str1, str2); // 交换两个字符串的内容
  • 填充字符串

    1
    str.assign(10, '*'); // 用字符'*'填充字符串,长度为10

6. 迭代器

  • 迭代器访问

    1
    2
    3
    4
    for (std::string::iterator it = str.begin(); it != str.end(); ++it) {
    // 访问和修改字符
    *it = toupper(*it);
    }
  • 常量迭代器

    1
    2
    3
    for (std::string::const_iterator it = str.cbegin(); it != str.cend(); ++it) {
    // 只能访问字符,不能修改
    }

这些笔记涵盖了std::string类的一些常用功能,但std::string的功能远不止这些。如果你需要更多详细信息,可以参考C++标准库文档或者相关书籍。