以下是一些常用的STL容器:
vector
:动态数组,提供快速的随机访问。list
:双向链表,支持快速插入和删除操作。set
:有序集合,存储唯一的元素。map
:有序映射,存储键值对。stack
:堆栈,先进后出(LIFO)的数据结构。queue
:队列,先进先出(FIFO)的数据结构。
算法
STL提供了丰富的算法库,包括排序、搜索、复制、替换、合并等各种常用算法。这些算法可以用于不同类型的容器,使得对数据进行各种操作变得简单高效。
以下是一些常用的STL算法:
sort
:对容器进行排序。find
:在容器中查找指定元素。copy
:将容器中的元素复制到另一个容器。replace
:替换容器中的元素。merge
:合并两个有序容器。reverse
:反转容器中的元素顺序
vector(动态数组)
vector
是一个动态数组,提供了连续的内存空间用于存储元素。它是最常用的容器之一,支持快速随机访问和动态调整大小。
头文件
#include <vector>
创建容器对象
std::vector<T> vec; // 创建一个空的 vector,元素类型为 T
std::vector<T> vec(n); // 创建包含 n 个默认初始化的元素的 vector
std::vector<T> vec(n, value); // 创建包含 n 个初始化为 value 的元素的 vector
vector<vector<Point2f> > points; //定义一个二维数组
常用成员函数
size():返回 vector 中的元素数量。
empty():检查 vector 是否为空。
push_back(value):在 vector 的末尾添加一个元素。
pop_back():删除 vector 的最后一个元素。
front():访问 vector 的第一个元素。
back():访问 vector 的最后一个元素。
clear():清空 vector 中的所有元素。
insert(position, value):在指定位置插入一个元素。
erase(position):删除指定位置的元素。
erase(begin, end):删除指定范围内的元素。
在c++11里,为for
循环,添加一个container
,它就会自动迭代:实现了对于vector
型变量vec
的内容打印,变量 i 遍历vector
中的每一个元素,直到vector
的结束
vector<int> vec; //定义一个vector型变量vec的内容打印
vec.push_back(10); // 向容器vec中添加10个元素
vec.push_back(20); //再向容器vec中添加20个元素
for(int i:vec)
cout << i << endl;
list(双向链表)
list
是一个双向链表,它支持高效的插入和删除操作,但不支持随机访问。它可以在任意位置进行元素的插入和删除,适用于需要频繁插入和删除操作的场景。
头文件
#include <list>
创建容器对象
std::list<T> lst; // 创建一个空的 list,元素类型为 T
std::list<T> lst(n); // 创建包含 n 个默认初始化的元素的 list
std::list<T> lst(n, value); // 创建包含 n 个初始化为 value 的元素的 list
常用成员函数
size():返回 list 中的元素数量。
empty():检查 list 是否为空。
push_back(value):在 list 的末尾添加一个元素。
push_front(value):在 list 的开头添加一个元素。
pop_back():删除 list 的最后一个元素。
pop_front():删除 list 的第一个元素。
front():访问 list 的第一个元素。
back():访问 list 的最后一个元素。
clear():清空 list 中的所有元素。
insert(position, value):在指定位置插入一个元素。
erase(position):删除指定位置的元素。
erase(begin, end):删除指定范围内的元素。
#include <iostream>
#include <list>
int main() {
std::list<int> lst; // 创建一个空的 list
lst.push_back(1); // 在末尾添加元素
lst.push_back(2);
lst.push_front(0); // 在开头添加元素
std::cout << "List size: " << lst.size() << std::endl; // 输出元素数量
std::cout << "List elements: ";
for (int num : lst) {
std::cout << num << " "; // 遍历并输出元素
}
std::cout << std::endl;
lst.pop_back(); // 删除最后一个元素
std::cout << "List size after pop_back(): " << lst.size() << std::endl;
std::cout << "New list elements: ";
for (int num : lst) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
map(关联容器)
map
是一个关联容器,它提供了一对一的键值对存储和访问功能。它基于红黑树
实现,具有自动排序的特性,键值对按键进行排序,并且可以快速地进行插入、删除和查找操作。
插入元素的键不允许重复,比较函数只对元素的键值进行
头文件
#include <map>
创建容器对象
std::map<Key, T> mp; // 创建一个空的 map,键类型为 Key,值类型为 T
std::map<Key, T> mp(other); // 创建另一个 map 的副本
常用成员函数
size():返回 map 中的键值对数量。
empty():检查 map 是否为空。
insert({key, value}):插入一个键值对到 map 中。
erase(key):删除指定键的键值对。
clear():清空 map 中的所有键值对。
find(key):查找指定键对应的迭代器。返回的是迭代器
begin():返回指向第一个键值对的迭代器。
end():返回指向最后一个键值对之后的迭代器。
coust(key):返回是否有键为key的元素,若有则返回1,若没有则返回0
pair是mp内部的存储结构,pair就是“一对”,第一个元素和第二个元素组成的一对,其中第一个元素叫做first,第二个元素叫second
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> mp; // 创建一个空的 map
mp.insert({"Alice", 25}); // 插入键值对
mp.insert({"Bob", 30});
mp["Charlie"] = 35; // 也可以使用索引操作符插入键值对
std::cout << "Map size: " << mp.size() << std::endl; // 输出键值对数量
std::cout << "Map elements:" << std::endl;
for (const auto& pair : mp) {
std::cout << pair.first << ": " << pair.second << std::endl; // 遍历并输出键值对
}
mp.erase("Bob"); // 删除指定键的键值对
std::cout << "Map size after erase(): " << mp.size() << std::endl;
std::cout << "New map elements:" << std::endl;
for (const auto& pair : mp) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
注意:map会自动对键进行排序,从小到大排序
set(关联容器)
set
是一个关联容器,它存储唯一的元素,且自动按照键进行排序。set
的底层实现基于红黑树,具有快速的插入、删除和查找操作。
因此set可以进行去重和排序操作
头文件
#include <set>
创建容器对象
std::set<T> st; // 创建一个空的 set,元素类型为 T
std::set<T> st(other); // 创建另一个 set 的副本
常用成员函数
size():返回 set 中的元素数量。
empty():检查 set 是否为空。当set为空时,返回真
insert(value):向 set 中插入一个元素。
erase(value):删除 set 中指定的元素。
clear():清空 set 中的所有元素。
find(value):查找 set 中是否存在指定的元素。返回的是迭代器
begin():返回指向第一个元素的迭代器。
end():返回指向最后一个元素之后的迭代器。
cout(x): 统计set中,x的数量,因此要么返回1,要么返回0
#include <iostream>
#include <set>
int main() {
std::set<int> st; // 创建一个空的 set
st.insert(10); // 插入元素
st.insert(20);
st.insert(30);
std::cout << "Set size: " << st.size() << std::endl; // 输出元素数量
std::cout << "Set elements: ";
for (int num : st) {
std::cout << num << " "; // 遍历并输出元素
}
std::cout << std::endl;
st.erase(20); // 删除指定元素
std::cout << "Set size after erase(): " << st.size() << std::endl;
std::cout << "New set elements: ";
for (int num : st) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
unordered_set
底层是hash
引入头文件:
#include <unordered_set>
unordered_set 容器,可直译为“无序 set 容器”。即 unordered_set 容器和 set 容器很像,唯一的区别就在于 set 容器会自行对存储的数据进行排序,而 unordered_set 容器不会。
unordered_set的几个特性:
创建容器对象
unordered_set<int> set1;
常用成员函数
size()函数,返回元素的数量
empty()函数——判断是否为空,若容器为空,则返回 true;否则 false
find()函数——查找,查找2,找到返回迭代器,失败返回end()
count(x)函数——出现次数,返回x出现的次数,0或1
insert()函数——插入元素
//插入元素,返回pair<unordered_set<int>::iterator, bool>
set1.insert(3);
//使用initializer_list插入元素
set1.insert({1,2,3});
//指定插入位置,如果位置正确会减少插入时间,返回指向插入元素的迭代器
set1.insert(set1.end(), 4);
//使用范围迭代器插入
set1.insert(set2.begin(), set2.end());
关于insert函数的返回值:
insert()只传入单个参数(待插入元素)
auto pr = words.insert("ninety");
emplace()函数——插入元素(转移构造)
//使用转移构造函数添加新元素3,比insert效率高
set1.emplace(3);
erase(x)函数——删除元素x
stack(适配器容器)
stack
是一个适配器容器,它提供了栈(先进后出)的行为。stack
内部使用其他容器作为其底层实现,默认情况下使用 deque
作为底层容器。
头文件
#include <stack>
创建容器对象
std::stack<T> stk; // 创建一个空的 stack,元素类型为 T
常用成员函数
size()
:返回 stack 中的元素数量。empty()
:检查 stack 是否为空。push(value)
:将元素压入 stack。pop()
:弹出 stack 的顶部元素。top()
:返回 stack 的顶部元素的引用。
#include <iostream>
#include <stack>
int main() {
std::stack<int> stk; // 创建一个空的 stack
stk.push(10); // 将元素压入 stack
stk.push(20);
stk.push(30);
std::cout << "Stack size: " << stk.size() << std::endl; // 输出元素数量
std::cout << "Stack top: " << stk.top() << std::endl; // 输出栈顶元素
stk.pop(); // 弹出栈顶元素
std::cout << "Stack size after pop(): " << stk.size() << std::endl;
std::cout << "New stack top: " << stk.top() << std::endl;
return 0;
}
queue(适配器容器)
queue
是一个适配器容器,它提供了队列(先进先出)的行为。queue
内部使用其他容器作为其底层实现,默认情况下使用 deque
作为底层容器。
头文件
#include <queue>
创建容器对象
std::queue<T> que; // 创建一个空的 queue,元素类型为 T
常用成员函数
size():返回 queue 中的元素数量。
empty():检查 queue 是否为空。
push(value):将元素加入到 queue 的末尾。
pop():移除 queue 的首个元素。
front():返回 queue 的首个元素的引用。
back():返回 queue 的末尾元素的引用。
#include <iostream>
#include <queue>
int main() {
std::queue<int> que; // 创建一个空的 queue
que.push(10); // 将元素加入到 queue 的末尾
que.push(20);
que.push(30);
std::cout << "Queue size: " << que.size() << std::endl; // 输出元素数量
std::cout << "Queue front: " << que.front() << std::endl; // 输出队首元素
std::cout << "Queue back: " << que.back() << std::endl; // 输出队尾元素
que.pop(); // 移除队首元素
std::cout << "Queue size after pop(): " << que.size() << std::endl;
std::cout << "New queue front: " << que.front() << std::endl;
return 0;
}
STL 算法
STL(标准模板库)提供了丰富的算法,用于在容器上执行各种操作。这些算法大大简化了对数据集合的处理,包括搜索、排序、转换等操作。
以下是一些常用的 STL 算法:
std::find():在容器中查找指定的元素。
std::sort():对容器中的元素进行排序。
std::reverse():反转容器中的元素顺序。
std::count():统计容器中某个值的出现次数。
std::accumulate():计算容器中元素的累加和。
std::transform():对容器中的元素应用一个操作,并将结果存储在另一个容器中。
std::copy():将一个容器中的元素复制到另一个容器中。
std::remove():从容器中删除指定的值。
std::unique():删除容器中的重复元素。
std::min_element():查找容器中的最小元素。
std::max_element():查找容器中的最大元素。
这些算法都是通过包含 <algorithm>
头文件来使用的。它们适用于不同类型的容器,包括数组、向量、列表、集合等。
下面是一个示例代码,演示了如何使用 STL 算法:
std::reverse()
算法用于反转容器中的元素顺序。
void reverse( BidirIt first, BidirIt last );
first
和last
:定义了容器中要进行反转的元素的范围。这个范围是一个双向迭代器可以在正向和反向方向上进行遍历。
下面是一个示例代码:
#include <iostream>
#include <algorithm>
#include <vector>
int main() {
std::vector<int> nums = {1, 2, 3, 4, 5};
std::reverse(nums.begin(), nums.end());
std::cout << "Reversed container: ";
for (int num : nums) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}