首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

C++ STL multimap 完整指南:重複鍵值關聯容器實戰

     編輯:關於VC++

前言

std::multimap 是標準庫中允許重複鍵值的關聯容器,底層同為紅黑樹,操作複雜度與 map 相同 (對數級)。適用於電話簿(一名多號)、DNS(多域名解析同 IP)、檔案系統硬連結等場景。本文詳細說明插入、查找、範圍存取、與 map 差異。

為什麼需要 multimap?

map 的 operator[] 單一回傳值,無法表達一鍵多值。標準庫解法:移除 operator[],改用 insert() 配合迭代器區間存取。

基本宣告與插入


#include <map>
#include <string>

multimap<string, string> phonebook;
phonebook.insert(make_pair("Harry", "8225687"));  // 家裡
phonebook.insert(make_pair("Harry", "555123123")); // 公司
phonebook.insert(make_pair("Harry", "2532532532")); // 手機

insert() 回傳值差異

容器insert() 回傳型別說明
multimapiterator指向新插入元素,永遠成功
mappair<iterator, bool>bool 表示是否插入成功 (鍵值不重複)

查找單一值


auto it = phonebook.find("Harry");
if (it != phonebook.end())
    cout << "第一筆: " << it->second << endl; // 僅取得第一筆

find(k) 回傳第一個匹配鍵值的迭代器,適合「是否存在」或「取第一筆」需求。

處理多重關聯值

1. count(k) - 統計筆數


cout << phonebook.count("Harry"); // 輸出 3

2. equal_range(k) - 取得完整範圍 (推薦)


typedef multimap<string, string>::const_iterator CI;
typedef pair<CI, CI> Range;

Range range = phonebook.equal_range("Harry");
for (CI it = range.first; it != range.second; ++it)
    cout << it->second << endl;
// 輸出所有 Harry 的電話

3. lower_bound / upper_bound - 邊界迭代器

  • lower_bound(k):第一個 ≥ k 的元素 (等同 equal_range.first)
  • upper_bound(k):第一個 > k 的元素 (等同 equal_range.second)

// 列印所有鍵值 > "Harry" 的記錄
auto it = phonebook.upper_bound("Harry");
while (it != phonebook.end())
{
    cout << it->first << " = " << it->second << endl;
    ++it;
}

DNS 後台程式實戰範例


multimap<string, string> dns; // IP → 域名

dns.insert(make_pair("213.108.96.7", "cppzone.com"));
dns.insert(make_pair("213.108.96.7", "cpluspluszone.com"));
dns.insert(make_pair("219.108.96.70", "pythonzone.com"));
dns.insert(make_pair("219.108.96.70", "python-zone.com"));

// 查詢單一 IP 的所有域名
auto range = dns.equal_range("213.108.96.7");
for (auto it = range.first; it != range.second; ++it)
    cout << it->second << endl;
// cpluspluszone.com
// cppzone.com

// 列印所有 IP > 213.108.96.7 的域名
for (auto it = dns.upper_bound("213.108.96.7"); it != dns.end(); ++it)
    cout << it->first << " → " << it->second << endl;

map vs multimap 選擇指南

場景選擇理由
鍵值唯一、需 operator[] 便利存取map語法簡潔、單值語義明確
一鍵多值、需遍歷所有關聯值multimap原生支援重複鍵、equal_range 高效
需頻繁統計鍵值出現次數multimapcount() O(log n + k)
鍵值唯一但需高效範圍查詢maplower/upper_bound 同樣適用

常見陷阱與注意事項

  1. 不可使用 operator[]:multimap 未提供,編譯錯誤
  2. insert() 永遠成功:不檢查重複,若需唯一性請用 map 或自行檢查
  3. 迭代器失效規則:插入/刪除不使其他迭代器失效 (紅黑樹特性)
  4. 自訂比較函數:multimap<Key, T, Compare, Alloc> 第三模板參數指定排序準則

結語

multimap 以「捨棄 operator[]」換取「原生重複鍵支援」,是處理一對多關聯的標準利器。掌握 insert/find/count/equal_range/lower_bound/upper_bound 完整介面,配合 make_pair 輔助函數,即可優雅解決電話簿、DNS、標籤系統等經典問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved