unordered_set
unordered_set 是 C++ 标准库中的一个无序关联容器,它存储的元素是唯一的,并且元素的插入、删除和查找操作平均时间复杂度为常数时间 O(1)(尽管在最坏情况下可能退化到 O(n),但这在实际情况中很少发生)。
unordered_set 内部通常实现为一个哈希表,这意味着它不会根据元素的任何特定顺序来存储元素。
基本操作
- 包含头文件:要使用 unordered_set,需要包含 <unordered_set> 头文件。
- 声明 unordered_set:使用模板语法声明 unordered_set,指定存储元素的类型。
- 插入元素:使用 insert() 方法插入元素。如果元素已存在,则插入操作将不会执行,且 unordered_set 的大小不会改变。
- 访问元素:由于 unordered_set 是无序的,并且不保证元素的顺序,因此没有直接的方法来“访问”特定索引的元素。但你可以使用迭代器来遍历容器中的所有元素。
- 删除元素:使用 erase() 方法删除元素,可以按值、迭代器或迭代器范围来删除。
- 查找元素:使用 find() 方法来查找具有特定值的元素,返回一个迭代器,指向找到的元素(如果找到的话)。
演示
#include <iostream>
#include <unordered_set>
#include <string>
int main() {
// 声明一个unordered_set,存储int类型的元素
std::unordered_set<int> myUnorderedSet;
// 插入元素
myUnorderedSet.insert(10);
myUnorderedSet.insert(20);
myUnorderedSet.insert(10); // 尝试插入已存在的元素,实际上不会增加任何内容
// 遍历unordered_set
std::cout << "Elements in myUnorderedSet: ";
for (int elem : myUnorderedSet) {
std::cout << elem << " ";
}
std::cout << std::endl;
// 查找元素
auto it = myUnorderedSet.find(20);
if (it != myUnorderedSet.end()) {
std::cout << "Found 20." << std::endl;
}
// 删除元素
myUnorderedSet.erase(10); // 注意:这会删除所有值为10的元素
// 再次遍历unordered_set以确认元素已被删除
std::cout << "After erasing 10: ";
for (int elem : myUnorderedSet) {
std::cout << elem << " ";
}
std::cout << std::endl;
// 插入字符串元素到另一个unordered_set
std::unordered_set<std::string> myStringSet;
myStringSet.insert("apple");
myStringSet.insert("banana");
// 使用范围for循环遍历字符串集
std::cout << "Elements in myStringSet: ";
for (const std::string& elem : myStringSet) {
std::cout << elem << " ";
}
std::cout << std::endl;
return 0;
}
unordered_map
unordered_map 是 C++ 标准库中的一个无序关联容器,它存储的元素是键值对(key-value pairs),其中每个键都是唯一的,并且每个键都映射到其对应的值。
unordered_map 内部通常实现为一个哈希表,这意味着它不会根据键的任何特定顺序来存储元素
基本操作
- 包含头文件:要使用 unordered_map,需要包含 <unordered_map> 头文件。
- 声明 unordered_map:使用模板语法声明 unordered_map,指定键和值的类型。
- 插入元素:使用 insert() 方法或下标操作符 [] 来插入键值对。如果键已存在,使用 insert() 方法将不会插入新元素,而使用下标操作符则会覆盖旧值。
- 访问元素:可以使用下标操作符 [] 或 at() 方法来访问与键相关联的值。下标操作符在键不存在时会插入一个具有该键的新元素(值类型默认构造),而 at() 方法在键不存在时会抛出一个 std::out_of_range 异常。
- 删除元素:使用 erase() 方法删除元素,可以按键、迭代器或迭代器范围来删除。
- 查找元素:使用 find() 方法来查找具有特定键的元素,返回一个迭代器,指向找到的元素(如果找到的话)。
演示
#include <iostream>
#include <unordered_map>
#include <string>
int main() {
// 声明一个unordered_map,键为std::string,值为int
std::unordered_map<std::string, int> myUnorderedMap;
// 使用insert()方法插入键值对
myUnorderedMap.insert(std::make_pair("apple", 100));
myUnorderedMap.insert({"banana", 200}); // C++11 列表初始化
// 使用下标操作符插入或修改键值对
myUnorderedMap["cherry"] = 300;
myUnorderedMap["apple"] = 150; // 修改apple的值
// 访问元素
std::cout << "The value of 'banana' is " << myUnorderedMap["banana"] << std::endl;
// 注意:如果'grape'不存在,以下行将插入一个键值对('grape', 0)
// std::cout << "The value of 'grape' is " << myUnorderedMap["grape"] << std::endl;
// 使用at()方法访问元素(更安全,但键不存在时会抛出异常)
try {
std::cout << "The value of 'apple' is " << myUnorderedMap.at("apple") << std::endl;
// std::cout << "The value of 'grape' is " << myUnorderedMap.at("grape") << std::endl; // 这将抛出std::out_of_range
} catch (const std::out_of_range& e) {
std::cout << "Key not found: " << e.what() << std::endl;
}
// 遍历unordered_map
for (const auto& pair : myUnorderedMap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
// 删除元素
myUnorderedMap.erase("banana"); // 按键删除
// 再次遍历以确认元素已被删除
std::cout << "After erasing 'banana':" << std::endl;
for (const auto& pair : myUnorderedMap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}