C++中unordered_multiset容器用法示例詳解
更新時間:2026年02月10日 08:30:58 作者:你的冰西瓜
這篇文章主要介紹了C++中unordered_multiset容器用法的相關資料,unordered_multiset是以key為元素無序的關聯(lián)容器,搜索、移除和插入操作是平均常數(shù)的時間復雜度,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
1.unordered_multiset概述
unordered_multiset是C++11引入的關聯(lián)容器,基于哈希表實現(xiàn),允許存儲重復元素,提供快速的查找、插入和刪除操作,平均時間復雜度為O(1)O(1)O(1)。
2. 基本特性
- 哈希表實現(xiàn):使用哈希函數(shù)組織元素
- 允許重復元素:容器中可以包含多個相同值
- 無序存儲:元素不以任何特定順序存儲
- 快速訪問:平均情況下提供常數(shù)時間復雜度的查找
- 動態(tài)大小:可以根據(jù)需要自動擴展
3. 頭文件與聲明
#include <unordered_set>
using namespace std;
unordered_multiset<int> ums1; // 空unordered_multiset
unordered_multiset<string> ums2 = {"a", "b", "a"}; // 初始化列表(允許重復)
unordered_multiset<double> ums3(10); // 初始桶數(shù)為10
4. 構造函數(shù)與初始化
4.1 默認構造
unordered_multiset<int> numbers;
4.2 范圍構造
int arr[] = {1, 2, 2, 3, 3, 3};
unordered_multiset<int> nums(arr, arr+6);
4.3 拷貝構造
unordered_multiset<int> ums2(ums1);
4.4 自定義哈希函數(shù)和相等比較
struct CaseInsensitiveHash {
size_t operator()(const string& s) const {
size_t h = 0;
for(char c : s) {
h += tolower(c);
}
return h;
}
};
struct CaseInsensitiveEqual {
bool operator()(const string& a, const string& b) const {
if(a.length() != b.length()) return false;
for(size_t i = 0; i < a.length(); ++i) {
if(tolower(a[i]) != tolower(b[i])) return false;
}
return true;
}
};
unordered_multiset<string, CaseInsensitiveHash, CaseInsensitiveEqual> case_insensitive_ms;
5. 容量操作
5.1size()
cout << ums.size(); // 返回元素總數(shù)量(包括重復)
5.2empty()
if(ums.empty()) {
cout << "unordered_multiset is empty";
}
5.3max_size()
cout << ums.max_size(); // 返回可容納的最大元素數(shù)
6. 元素訪問
6.1 迭代器訪問
for(auto it = ums.begin(); it != ums.end(); ++it) {
cout << *it << " ";
}
7. 修改操作
7.1insert()
ums.insert(10); // 插入單個元素
ums.insert({5, 5, 15}); // 插入初始化列表(允許重復)
ums.insert(arr, arr+3); // 插入范圍
auto it = ums.insert(20); // 返回指向插入元素的迭代器
7.2emplace()
auto it = ums.emplace(30); // 原地構造元素
7.3erase()
ums.erase(5); // 刪除所有值為5的元素
auto it = ums.find(10);
if(it != ums.end()) {
ums.erase(it); // 只刪除一個10
}
ums.erase(ums.begin(), ums.end()); // 刪除范圍
7.4clear()
ums.clear(); // 清空所有元素
7.5swap()
unordered_multiset<int> ums2; ums.swap(ums2); // 交換兩個unordered_multiset
8. 查找操作
8.1find()
auto it = ums.find(10); // 返回指向第一個10的迭代器
if(it != ums.end()) {
cout << "Found: " << *it;
}
8.2count()
cout << ums.count(5); // 返回元素5的數(shù)量
8.3equal_range()
auto range = ums.equal_range(15); // 返回等于15的元素范圍[pair]
for(auto it = range.first; it != range.second; ++it) {
cout << *it << " ";
}
9. 桶操作
9.1bucket_count()
cout << ums.bucket_count(); // 返回桶的數(shù)量
9.2max_bucket_count()
cout << ums.max_bucket_count(); // 返回最大桶數(shù)
9.3bucket_size()
cout << ums.bucket_size(2); // 返回第2個桶中的元素數(shù)
9.4bucket()
cout << ums.bucket("apple"); // 返回"apple"所在的桶索引
10. 哈希策略
10.1load_factor()
cout << ums.load_factor(); // 返回負載因子(元素數(shù)/桶數(shù))
10.2max_load_factor()
cout << ums.max_load_factor(); // 返回最大負載因子 ums.max_load_factor(0.75); // 設置最大負載因子
10.3rehash()
ums.rehash(20); // 設置桶數(shù)為至少20
10.4reserve()
ums.reserve(100); // 預留空間至少容納100個元素
11. 完整示例
#include <iostream>
#include <unordered_set>
#include <string>
using namespace std;
int main() {
// 創(chuàng)建并初始化unordered_multiset
unordered_multiset<string> words = {"apple", "banana", "apple", "orange", "banana"};
// 插入元素
words.insert("grape");
words.emplace("pear");
words.insert({"apple", "kiwi", "kiwi"});
// 查找元素
cout << "Number of 'apple': " << words.count("apple") << endl;
auto found = words.find("orange");
if(found != words.end()) {
cout << "Found orange at bucket #" << words.bucket(*found) << endl;
}
// 遍歷unordered_multiset
cout << "All words: ";
for(const auto& word : words) {
cout << word << " ";
}
cout << endl;
// 使用equal_range處理重復元素
cout << "All apples: ";
auto range = words.equal_range("apple");
for(auto it = range.first; it != range.second; ++it) {
cout << *it << " ";
}
cout << endl;
// 刪除元素
words.erase("banana"); // 刪除所有banana
auto it = words.find("kiwi");
if(it != words.end()) {
words.erase(it); // 只刪除一個kiwi
}
// 桶信息
cout << "\nBucket information:" << endl;
cout << "Number of buckets: " << words.bucket_count() << endl;
cout << "Current load factor: " << words.load_factor() << endl;
// 調整哈希表
words.rehash(15);
cout << "After rehash, bucket count: " << words.bucket_count() << endl;
// 容量信息
cout << "\nSize: " << words.size() << endl;
cout << "Is empty: " << (words.empty() ? "Yes" : "No") << endl;
return 0;
}
12. 性能提示
- 平均情況下查找、插入、刪除時間復雜度為O(1)O(1)O(1)
- 最壞情況下(哈希沖突嚴重)時間復雜度退化為O(n)O(n)O(n)
- 負載因子過高會影響性能,可適時
rehash() - 自定義類型需要提供哈希函數(shù)和相等比較
- 迭代器在插入操作后可能失效(重新哈希時)
13. 與multiset比較
| 特性 | unordered_multiset | multiset |
|---|---|---|
| 實現(xiàn)方式 | 哈希表 | 紅黑樹 |
| 元素順序 | 無序 | 自動排序 |
| 查找復雜度 | 平均O(1)O(1)O(1) | O(log?2n)O(\log_2 n)O(log2?n) |
| 內存使用 | 通常較少 | 通常較多 |
| 迭代器穩(wěn)定性 | 插入可能失效 | 穩(wěn)定(除刪除元素) |
14. 與unordered_set比較
| 特性 | unordered_multiset | unordered_set |
|---|---|---|
| 元素唯一性 | 允許重復 | 不允許重復 |
count()返回值 | 可能大于111 | 000或111 |
equal_range() | 常用于處理重復 | 較少使用 |
總結
到此這篇關于C++中unordered_multiset容器用法詳解的文章就介紹到這了,更多相關C++中unordered_multiset容器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++實現(xiàn)從數(shù)組中同時取出最大最小元素算法示例
這篇文章主要介紹了C++實現(xiàn)從數(shù)組中同時取出最大最小元素算法,結合具體實例形式分析了C++通過數(shù)組的遍歷、排序獲取最大與最小元素的相關操作技巧,需要的朋友可以參考下2017-09-09

