STL标准模板库笔记
STL标准模板库
STL 概念
STL(标准模板库)是C++标准库的重要组成部分,它提供了一系列常用的数据结构和算法,极大地丰富了C++的功能。STL主要包含以下几个部分:
一、容器(Containers)
STL提供了多种容器,每种容器都有其特定的用途和性能特征。常见的容器包括:
- vector:动态数组,支持快速随机访问和尾部插入删除。
- deque:双端队列,支持快速随机访问和两端插入删除。
- list:双向链表,支持双向遍历和任意位置插入删除。
- forward_list:单向链表,支持单向遍历和任意位置插入删除。
- set:有序集合,元素唯一且自动排序。
- multiset:有序多重集合,元素可以重复且自动排序。
- map:有序映射,键值对集合,键唯一且自动排序。
- multimap:有序多重映射,键可以重复且自动排序。
- unordered_set:无序集合,元素唯一,无序存储。
- unordered_multiset:无序多重集合,元素可以重复,无序存储。
- unordered_map:无序映射,键值对集合,键唯一,无序存储。
- unordered_multimap:无序多重映射,键可以重复,无序存储。
此外,STL还提供了基于容器的适配器,如栈(stack)、队列(queue)和优先队列(priority_queue),它们分别基于deque、list或vector等容器实现。
二、迭代器(Iterators)
迭代器是一种广义指针,提供了对容器和容器元素的通用访问方法。STL中的算法通过迭代器来操作容器,将算法与特定容器的实现解耦。迭代器分为以下几类:
- 输入迭代器:只读访问容器中的元素,支持单向遍历。
- 输出迭代器:只能写入元素,不能读取,支持单向遍历。
- 前向迭代器:支持只读或读写访问,支持单向遍历,允许多次遍历相同的元素。
- 双向迭代器:支持双向遍历,既可以向前遍历,也可以向后遍历。
- 随机访问迭代器:支持随机访问,可以直接跳转到容器中的任意元素,是功能最强的迭代器类型。
三、算法(Algorithms)
STL提供了大量的算法,涵盖了排序、搜索、数值操作、生成和修改序列等常见任务。这些算法可以直接应用于容器,也可以通过迭代器应用于数组或其他数据结构。常见的算法包括:
- 查找和排序:如find、count、sort、binary_search、merge等。
- 修改和操作:如copy、transform、replace、fill、swap、reverse等。
- 数值操作:如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类似,支持
insert
、erase
、size
、empty
等操作。
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。 - 数值算法:如
equal
、includes
、max_element
、min_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 |
|
在这个示例中,我们创建了一个 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
2char c_str[] = "Hello";
std::string str(c_str, 5); // 使用字符数组的前5个字符初始化用单个字符重复n次构造
1
std::string str(5, 'a'); // 创建一个字符串 "aaaaa"
用另一个
std::string
对象构造1
2std::string str1("Hello");
std::string str2(str1); // 使用str1初始化str2
2. 访问与修改
访问单个字符
1
2char ch = str[0]; // 访问第一个字符
str[0] = 'h'; // 修改第一个字符获取字符串的C风格表示
1
const char* c_str = str.c_str(); // 获取C风格字符串(以null结尾)
字符串拼接
1
2str += " 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
4for (std::string::iterator it = str.begin(); it != str.end(); ++it) {
// 访问和修改字符
*it = toupper(*it);
}常量迭代器
1
2
3for (std::string::const_iterator it = str.cbegin(); it != str.cend(); ++it) {
// 只能访问字符,不能修改
}
这些笔记涵盖了std::string
类的一些常用功能,但std::string
的功能远不止这些。如果你需要更多详细信息,可以参考C++标准库文档或者相关书籍。