当涉及到常见的容器 std::set
、std::map
、std::unordered_map
、和 std::unordered_set
时,它们的主要特点和使用情况可以总结如下:
四种增删查改
-
std::set
:- 用途:存储一组元素并保持唯一性,自动排序。
- 特点:
- 元素唯一,不允许重复。
- 自动按照元素的排序准则进行排序。
- 查找、插入和删除的平均时间复杂度为 O(log n)。
- 常用操作:
insert(value)
: 插入一个元素value
。erase(value)
: 删除与给定值value
相等的元素。count(value)
: 返回与给定值value
相等的元素的数量。find(value)
: 返回指向容器中第一个与给定值value
相等的元素的迭代器。
-
std::map
:- 用途:存储键值对,并根据键进行查找和访问。
- 特点:
- 键值对唯一,每个键只能关联一个值。
- 根据键自动排序。
- 查找、插入和删除的平均时间复杂度为 O(log n)。
- 常用操作:
insert({key, value})
: 插入一个键值对{key, value}
。erase(key)
: 删除与给定键key
相等的键值对。count(key)
: 返回与给定键key
相等的键值对的数量。find(key)
: 返回指向容器中第一个与给定键key
相等的键值对的迭代器。
-
std::unordered_map
:- 用途:存储键值对,并快速根据键进行查找和访问。
- 特点:
- 键值对唯一,每个键只能关联一个值。
- 不保持特定的顺序,使用哈希表实现。
- 查找、插入和删除的平均时间复杂度为 O(1)。
- 常用操作:
insert({key, value})
: 插入一个键值对{key, value}
。erase(key)
: 删除与给定键key
相等的键值对。count(key)
: 返回与给定键key
相等的键值对的数量。find(key)
: 返回指向容器中第一个与给定键key
相等的键值对的迭代器。
-
std::unordered_set
:- 用途:存储一组元素,并快速检查元素的唯一性。
- 特点:
- 元素唯一,不允许重复。
- 不保持特定的顺序,使用哈希表实现。
- 查找、插入和删除的平均时间复杂度为 O(1)。
- 常用操作:
insert(value)
: 插入一个元素value
。erase(value)
: 删除与给定值value
相等的元素。count(value)
: 返回与给定值value
相等的元素的数量。find(value)
: 返回指向容器中第一个与给定值value
相等的元素的迭代器
对元素的获取
对元素的获取:用迭代器
当涉及到常见的容器 std::set
、std::map
、std::unordered_map
、和 std::unordered_set
时,你可以使用以下方法来获取容器的头元素和尾元素:
-
std::set
和std::unordered_set
:- 头元素:可以使用
*set.begin()
来获取集合的头元素,即最小的元素。 - 尾元素:可以使用
*set.rbegin()
来获取集合的尾元素,即最大的元素。
- 头元素:可以使用
-
std::map
和std::unordered_map
:- 头元素:可以使用
map.begin()->first
来获取键值对集合的头元素的键,或者使用map.begin()->second
来获取头元素的值。 - 尾元素:可以使用
map.rbegin()->first
来获取键值对集合的尾元素的键,或者使用map.rbegin()->second
来获取尾元素的值。
- 头元素:可以使用
请注意,上述方法假设容器不为空。在访问头元素或尾元素之前,最好确保容器不为空,否则可能会导致未定义行为。
另外,如果你只想获取容器的头元素或尾元素的迭代器而不是元素本身,可以使用 begin()
和 end()
方法来获取容器的起始迭代器和结束迭代器,然后使用 --
操作符来获取尾迭代器的前一个位置的迭代器。例如:
-
std::set
和std::unordered_set
:- 头元素迭代器:
set.begin()
- 尾元素迭代器:
--set.end()
- 头元素迭代器:
-
std::map
和std::unordered_map
:- 头元素迭代器:
map.begin()
- 尾元素迭代器:
--map.end()
- 头元素迭代器:
这样你就可以使用迭代器来访问容器的头元素和尾元素。
vector,set,map,unorder_set,unorder_map几种遍历方法
以下是分别遍历不同容器类型的示例代码:
遍历 std::vector
:
#include <iostream>
#include <vector>
int main() {
std::vector<int> myVector = {1, 2, 3, 4, 5};
// 使用下标遍历 vector
for (size_t i = 0; i < myVector.size(); ++i) {
std::cout << myVector[i] << " ";
}
std::cout << std::endl;
// 使用迭代器遍历 vector
for (auto it = myVector.begin(); it != myVector.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 使用范围-based for 循环遍历 vector
for (const auto& element : myVector) {
std::cout << element << " ";
}
std::cout << std::endl;
return 0;
}
遍历 std::set
:
#include <iostream>
#include <set>
int main() {
std::set<int> mySet = {1, 2, 3, 4, 5};
// 使用迭代器遍历 set
for (auto it = mySet.begin(); it != mySet.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 使用范围-based for 循环遍历 set
for (const auto& element : mySet) {
std::cout << element << " ";
}
std::cout << std::endl;
return 0;
}
遍历 std::map
:
#include <iostream>
#include <map>
int main() {
std::map<int, std::string> myMap = {{1, "one"}, {2, "two"}, {3, "three"}};
// 使用迭代器遍历 map
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
std::cout << it->first << ": " << it->second << std::endl;
}
std::cout << std::endl;
// 使用范围-based for 循环遍历 map
for (const auto& pair : myMap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
std::cout << std::endl;
return 0;
}
遍历 std::unordered_set
:
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<int> myUnorderedSet = {1, 2, 3, 4, 5};
// 使用迭代器遍历 unordered_set
for (auto it = myUnorderedSet.begin(); it != myUnorderedSet.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 使用范围-based for 循环遍历 unordered_set
for (const auto& element : myUnorderedSet) {
std::cout << element << " ";
}
std::cout << std::endl;
return 0;
}
遍历 std::unordered_map
:
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<int, std::string> myUnorderedMap = {{1, "one"}, {2, "two"}, {3, "three"}};
// 使用迭代器遍历 unordered_map
for (auto it = myUnorderedMap.begin(); it != myUnorderedMap.end(); ++it) {
std::cout << it->first << ": " << it->second << std::endl;
}
std::cout << std::endl;
// 使用范围-based for 循环遍历 unordered_map
for (const auto& pair : myUnorderedMap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
std::cout << std::endl;
return 0;
}
这些示例代码演示了使用不同容器类型的迭代器或范围-based for 循环来遍历它们的元素。请根据您所使用的容器类型选择相应的遍历方法。
小注意:
当使用 map
的索引操作符 []
访问一个键时,如果该键不存在于 map
中,它会自动将该键插入到 map
中,并关联一个默认构造的值。
当执行 mp[key]
时,map
会首先查找是否存在具有给定键的条目。如果存在,则返回与该键关联的值;如果不存在,则会在 map
中插入一个新的键值对,并使用默认构造函数创建一个值对象,然后返回这个新插入的值对象的引用。