哈希表中鍵不可以重複但是值可以重複

 哈希表的初始化

#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;
    }
}
// 函數結束