哈希表中鍵不可以重複但是值可以重複
哈希表的初始化
#include <iostream>
#include <unordered_map> // 包含哈希表頭文件
#include <string>
using namespace std;
int main() {
// 1. 聲明和初始化哈希表
// 創建一個鍵為string類型,值為int類型的哈希表
unordered_map<string, int> ageMap;
// 2. 插入鍵值對的三種方法
// 方法1:使用insert函數和pair
ageMap.insert(pair<string, int>("Alice", 25));
// 方法2:使用insert函數和make_pair
ageMap.insert(make_pair("Bob", 30));
// 方法3:使用下標操作符(如果鍵不存在會自動創建)
ageMap["Charlie"] = 28;
// 3. 訪問元素
// 使用下標操作符訪問(如果鍵不存在會創建新元素)
cout << "Alice的年齡: " << ageMap["Alice"] << endl;
// 使用at函數訪問(如果鍵不存在會拋出異常,更安全)
cout << "Bob的年齡: " << ageMap.at("Bob") << endl;
// 4. 檢查鍵是否存在
// 使用find函數,如果找到返回迭代器,否則返回end()
if (ageMap.find("David") != ageMap.end()) {
cout << "David存在於哈希表中" << endl;
} else {
cout << "David不存在於哈希表中" << endl;
}
// 5. 遍歷哈希表
cout << "\n遍歷哈希表方法1:" << endl;
// 方法1:使用迭代器
for (auto it = ageMap.begin(); it != ageMap.end(); ++it) {
// it->first 是鍵,it->second 是值
cout << "姓名: " << it->first << ", 年齡: " << it->second << endl;
}
cout << "\n遍歷哈希表方法2:" << endl;
// 方法2:使用範圍for循環(C++11)
for (const auto& pair : ageMap) {
cout << "姓名: " << pair.first << ", 年齡: " << pair.second << endl;
}
// 6. 修改元素
// 如果鍵存在,修改對應的值
ageMap["Alice"] = 26; // 更新Alice的年齡
cout << "\n更新後Alice的年齡: " << ageMap["Alice"] << endl;
// 7. 刪除元素
// 方法1:通過鍵刪除
ageMap.erase("Bob");
cout << "刪除Bob後哈希表大小: " << ageMap.size() << endl;
// 方法2:通過迭代器刪除
auto it = ageMap.find("Charlie");
if (it != ageMap.end()) {
ageMap.erase(it);
}
// 8. 其他常用操作
// 獲取哈希表大小(元素個數)
cout << "當前哈希表大小: " << ageMap.size() << endl;
// 檢查哈希表是否為空
cout << "哈希表是否為空: " << (ageMap.empty() ? "是" : "否") << endl;
// 清空哈希表
ageMap.clear();
cout << "清空後哈希表大小: " << ageMap.size() << endl;
return 0;
}
判斷容量
void capacityFunctions() {
unordered_map<int, string> map = {{1, "one"}, {2, "two"}};
// empty() - 檢查容器是否為空
bool isEmpty = map.empty(); // 返回false
// size() - 返回元素數量
size_t elementCount = map.size(); // 返回2
// max_size() - 返回可容納的最大元素數
size_t maxElements = map.max_size();
cout << "是否為空: " << isEmpty << endl;
cout << "元素數量: " << elementCount << endl;
cout << "最大容量: " << maxElements << endl;
}
訪問成員函數和異常訪問方式
void accessFunctions() {
unordered_map<string, int> ageMap = {{"Alice", 25}, {"Bob", 30}};
// operator[] - 訪問或插入元素
ageMap["Charlie"] = 28; // 插入新元素
int aliceAge = ageMap["Alice"]; // 訪問現有元素
// at() - 安全訪問,會檢查邊界
try {
int bobAge = ageMap.at("Bob"); // 正常訪問
int davidAge = ageMap.at("David"); // 拋出std::out_of_range異常
} catch (const out_of_range& e) {
cout << "鍵不存在: " << e.what() << endl;
}
}
//try異常訪問
try {
int bobAge = ageMap.at("Bob"); // 正常訪問,不會拋出異常
int davidAge = ageMap.at("David"); // 鍵不存在,拋出std::out_of_range異常
} catch (const out_of_range& e) {
cout << "鍵不存在: " << e.what() << endl;
}
//當try塊中拋出異常時,程序跳轉到匹配的catch塊
//const out_of_range& e:捕獲out_of_range類型的異常
//e是異常對象的引用
查找成員函數
void lookupFunctions() {
unordered_map<string, int> map = {{"apple", 5}, {"banana", 3}};
// find() - 查找元素,返回迭代器
auto it = map.find("apple");
if (it != map.end()) {
cout << "找到apple: " << it->second << endl;
}
// count() - 返回匹配鍵的數量(0或1)
size_t count = map.count("banana"); // 返回1
count = map.count("cherry"); // 返回0
// equal_range() - 返回匹配鍵的範圍(對unordered_map用處有限)
auto range = map.equal_range("apple");// 查找鍵為"apple"的所有元素
for (auto i = range.first; i != range.second; ++i) { //i++和++i對輸出沒用影響
cout << i->first << ": " << i->second << endl; //i->first:訪問鍵(key),i->second:訪問值(value)
}
// contains() - C++20引入,檢查是否包含鍵
#if __cplusplus >= 202002L
bool hasApple = map.contains("apple"); // 返回true
#endif
}
桶成員函數
void bucketFunctions() {
unordered_map<int, string> map = {{1, "one"}, {2, "two"}, {3, "three"}};
// bucket_count() - 返回桶的數量
size_t bucketCount = map.bucket_count();
cout << "桶數量: " << bucketCount << endl;
// max_bucket_count() - 最大桶數量
size_t maxBuckets = map.max_bucket_count();
// bucket_size(n) - 返回第n個桶中的元素數量
for (size_t i = 0; i < bucketCount; ++i) {
cout << "桶 " << i << " 有 " << map.bucket_size(i) << " 個元素" << endl;
}
// bucket(key) - 返回鍵所在的桶索引
size_t bucketIndex = map.bucket(2);
cout << "鍵2在桶: " << bucketIndex << endl;
}
哈希策略成員函數
void hashPolicyFunctions() {
unordered_map<int, string> map;
// load_factor() - 當前負載因子
float currentLoad = map.load_factor();
// max_load_factor() - 獲取或設置最大負載因子
float maxLoad = map.max_load_factor(); // 獲取
map.max_load_factor(0.75f); // 設置
// rehash(n) - 設置桶的數量為至少n
map.rehash(20);
// reserve(n) - 預留空間用於至少n個元素
map.reserve(100);
cout << "當前負載因子: " << currentLoad << endl;
cout << "最大負載因子: " << maxLoad << endl;
}
觀察器成員函數
void observerFunctions() {
unordered_map<string, int> map;
// hash_function() - 返回哈希函數對象
auto hashFunc = map.hash_function();
size_t hashValue = hashFunc("test");
// key_eq() - 返回鍵比較函數對象
auto keyEqual = map.key_eq();
bool keysEqual = keyEqual("a", "a");
// get_allocator() - 返回分配器
auto allocator = map.get_allocator();
cout << "字符串'test'的哈希值: " << hashValue << endl;
cout << "鍵比較結果: " << keysEqual << endl;
}
迭代器成員函數
// 定義一個名為 iteratorFunctions 的函數,返回類型為 void(不返回值)
void iteratorFunctions() {
// 創建一個 unordered_map(哈希表),鍵為 int 類型,值為 string 類型
// 並用初始化列表初始化三個鍵值對:1->"one", 2->"two", 3->"three"
unordered_map<int, string> map = {{1, "one"}, {2, "two"}, {3, "three"}};
// 輸出提示信息,表示接下來是正序遍歷
cout << "正序遍歷:" << endl;
// 開始 for 循環,使用迭代器遍歷哈希表
// map.begin() 返回指向第一個元素的迭代器
// map.end() 返回指向最後一個元素之後位置的迭代器
// ++it 每次循環將迭代器向前移動一個位置
for (auto it = map.begin(); it != map.end(); ++it) {
// 通過迭代器訪問當前元素的鍵和值
// it->first 獲取鍵(key),it->second 獲取值(value)
cout << it->first << ": " << it->second << endl;
}
// 輸出提示信息,表示接下來使用 const 迭代器遍歷
cout << "const迭代器遍歷:" << endl;
// 開始 for 循環,使用 const 迭代器遍歷
// map.cbegin() 返回指向第一個元素的 const 迭代器(不能修改元素)
// map.cend() 返回指向最後一個元素之後位置的 const 迭代器
for (auto it = map.cbegin(); it != map.cend(); ++it) {
// 通過 const 迭代器訪問元素(只能讀取,不能修改)
cout << it->first << ": " << it->second << endl;
}
// 開始遍歷哈希表的每個桶(bucket)
// map.bucket_count() 返回哈希表中桶的總數量
// size_t i = 0 初始化循環計數器,從第0個桶開始
// i < map.bucket_count() 循環條件,遍歷所有桶
// ++i 每次循環計數器加1
for (size_t i = 0; i < map.bucket_count(); ++i) {
// 輸出當前桶的編號
cout << "桶" << i << "中的元素: ";
// 開始內層循環,遍歷當前桶中的所有元素
// map.begin(i) 返回指向第i個桶中第一個元素的迭代器
// map.end(i) 返回指向第i個桶中最後一個元素之後位置的迭代器
for (auto local_it = map.begin(i); local_it != map.end(i); ++local_it) {
// 輸出當前元素的鍵
cout << local_it->first << " ";
}
// 換行,結束當前桶的輸出
cout << endl;
}
}
// 函數結束
本文章為轉載內容,我們尊重原作者對文章享有的著作權。如有內容錯誤或侵權問題,歡迎原作者聯繫我們進行內容更正或刪除文章。