C++容器map
- 构造函数
- 1、默认构造函数
- 2、初始化列表构造函数
- 3、范围构造函数
- 4、拷贝构造函数
- 5、移动构造函数
- 元素访问
- 迭代器
- 容量大小
- 修改函数
- 查找计数
- 时间复杂度
https://cppreference.cn/w/cpp/container/map
存储唯一的、经过排序的键值对(key-value pairs)。可以通过唯一的键(key)来快速查找、插入或删除对应的值(value)。map 内部通常基于平衡二叉搜索树(如红黑树)实现
- 键值对:
map 存储的是 std::pair<const Key, T> 类型的对象,其中 Key 是键,T 是值 - 唯一性:每个键在
map 中都是唯一的。尝试插入一个已存在的键会失败 - 有序性:元素根据键自动排序。默认按升序排列(使用
std::less<Key>) - 平衡树实现:通常使用红黑树,保证了 O(log n) 的时间复杂度
- 不可变键:一旦插入,键的值不能被修改(因为键是
const 的),否则会破坏排序。如果需要“修改”键,必须先删除再重新插入
构造函数
1、默认构造函数
std::string getStringFromU8string(const std::u8string& u8str) {return std::string(reinterpret_cast<const char*>(u8str.data()), u8str.size());
}std::u8string getU8stingFromString(const std::string& str) {return std::u8string(reinterpret_cast<const char8_t*>(str.data()), str.size());
}
int main()
{system("chcp 65001");std::map<std::u8string, int> map1;map1.insert({ u8"北京", 3 });cout << "map1.size()-> " << map1.size() << endl;cout << "map1.max_size()-> " << map1.max_size() << endl;cout << "map1.empty()-> " << boolalpha << map1.empty() << endl;for (auto it : map1){cout << "key=" << getStringFromU8string(it.first) << ", value=" << it.second << endl;}
}
2、初始化列表构造函数
int main()
{system("chcp 65001");std::map<std::u8string, int> map1 = { {u8"北京",3},{u8"上海",4} };cout << "map1.size()-> " << map1.size() << endl;cout << "map1.max_size()-> " << map1.max_size() << endl;cout << "map1.empty()-> " << boolalpha << map1.empty() << endl;for (auto it : map1){cout << "key=" << getStringFromU8string(it.first) << ", value=" << it.second << endl;}
}
3、范围构造函数
int main()
{system("chcp 65001");std::vector<std::pair<std::u8string, int>> vec1 = {{u8"北京",3},{u8"上海",4}};std::map<std::u8string, int> map1(vec1.begin(), vec1.end());cout << "map1.size()-> " << map1.size() << endl;cout << "map1.max_size()-> " << map1.max_size() << endl;cout << "map1.empty()-> " << boolalpha << map1.empty() << endl;for (auto it : map1){cout << "key=" << getStringFromU8string(it.first) << ", value=" << it.second << endl;}
}
4、拷贝构造函数
int main()
{system("chcp 65001");std::map<std::u8string, int> map1 = {{u8"北京",3},{u8"上海",4}};std::map<std::u8string, int> map2(map1);cout << "map2.size()-> " << map2.size() << endl;cout << "map2.max_size()-> " << map2.max_size() << endl;cout << "map2.empty()-> " << boolalpha << map2.empty() << endl;for (auto it : map2){cout << "key=" << getStringFromU8string(it.first) << ", value=" << it.second << endl;}
}
5、移动构造函数
int main()
{system("chcp 65001");std::map<std::u8string, int> map1 = {{u8"北京",3},{u8"上海",4}};std::map<std::u8string, int> map2(std::move(map1));cout << "map1.size()-> " << map1.size() << endl;cout << "map2.max_size()-> " << map2.max_size() << endl;cout << "map2.empty()-> " << boolalpha << map2.empty() << endl;for (auto it : map2){cout << "key=" << getStringFromU8string(it.first) << ", value=" << it.second << endl;}
}
元素访问
| 函数 | 描述 |
|---|
m[key] | 下标访问。如果 key 不存在,会插入一个用默认值构造的 T 并返回其引用。如果存在,返回对应值的引用 |
m.at(key) | 访问键 key 对应的值。如果 key 不存在,抛出 std::out_of_range 异常 |
int main()
{system("chcp 65001");std::map<std::u8string, int> map1 = {{u8"北京",3},{u8"上海",4}};cout << "map1.size()-> " << map1.size() << endl;cout << "map1.max_size()-> " << map1.max_size() << endl;cout << "map1.empty()-> " << boolalpha << map1.empty() << endl;cout << "map1[]-> " << map1[u8"测试"] << endl;cout << "map1[]-> " << map1.at(u8"测试") << endl;for (auto it : map1){cout << "key=" << getStringFromU8string(it.first) << ", value=" << it.second << endl;}
}
迭代器
| 函数 | 描述 |
|---|
begin() / end() | 返回指向首元素和尾后位置的正向迭代器。 |
rbegin() / rend() | 返回指向末元素和首前位置的反向迭代器。 |
cbegin() / cend() | 返回常量正向迭代器。 |
crbegin() / crend() | 返回常量反向迭代器。 |
int main()
{system("chcp 65001");std::map<std::u8string, int> map1 = {{u8"北京",3},{u8"上海",4}};for (auto it : map1){cout << "key=" << getStringFromU8string(it.first) << ", value=" << it.second << endl;}for (auto it = map1.begin(); it != map1.end(); it++){cout << "begin-end, key=" << getStringFromU8string(it->first) << ", value=" << it->second << endl;}for (auto it = map1.cbegin(); it != map1.cend(); it++){cout << "cbegin-cend, key=" << getStringFromU8string(it->first) << ", value=" << it->second << endl;}for (auto it = map1.rbegin(); it != map1.rend(); it++){cout << "rbegin-rend, key=" << getStringFromU8string(it->first) << ", value=" << it->second << endl;}for (auto it = map1.crbegin(); it != map1.crend(); it++){cout << "crbegin-crend, key=" << getStringFromU8string(it->first) << ", value=" << it->second << endl;}
}
容量大小
| 函数 | 描述 |
|---|
empty() | 如果 map 为空,返回 true |
size() | 返回元素数量 |
max_size() | 返回容器可容纳的最大元素数量 |
int main()
{system("chcp 65001");std::map<std::u8string, int> map1 = {{u8"北京",3},{u8"上海",4}};cout << "map1.size()-> " << map1.size() << endl;cout << "map1.max_size()-> " << map1.max_size() << endl;cout << "map1.empty()-> " << boolalpha << map1.empty() << endl;
}
修改函数
| 函数 | 描述 |
|---|
insert(pair) | 插入一个 std::pair。返回 std::pair<iterator, bool>,bool 表示是否插入成功 |
insert({key, value}) | 直接插入键值对 |
insert(hint, pair) | 提供插入位置的提示 hint,可能提高效率 |
emplace(args...) | 就地构造一个 std::pair 并插入。返回 std::pair<iterator, bool> |
erase(key) | 删除键为 key 的元素,返回删除的元素数量(0 或 1) |
erase(it) | 删除迭代器 it 指向的元素 |
erase(first, last) | 删除范围 [first, last) 的元素 |
clear() | 删除所有元素 |
swap(other) | 与另一个 map 交换内容 |
int main()
{system("chcp 65001");std::map<std::u8string, int> map1 = {{u8"北京",3},{u8"上海",4}};map1.insert({ u8"广州",5 });map1.insert(std::pair(u8"深圳", 6));map1.insert(map1.begin(), std::pair(u8"测试", 7));map1.emplace(std::pair(u8"哈哈", 8));map1.try_emplace(u8"呵呵", 9);cout << "map1.size()-> " << map1.size() << endl;cout << "map1.max_size()-> " << map1.max_size() << endl;cout << "map1.empty()-> " << boolalpha << map1.empty() << endl;for (auto it : map1){cout << "insert,key=" << getStringFromU8string(it.first) << ", value=" << it.second << endl;}map1.erase(u8"哈哈");map1.erase(++map1.begin());map1.erase(++map1.begin(), --map1.end());for (auto it : map1){cout << "erase,key=" << getStringFromU8string(it.first) << ", value=" << it.second << endl;}map1.clear();
}
查找计数
| 函数 | 描述 |
|---|
find(key) | 查找 key,返回指向它的迭代器;未找到返回 m.end() |
count(key) | 返回 key 在 map 中的数量(0 或 1) |
contains(key) | (C++20) 检查 key 是否存在于 map 中,返回 bool |
lower_bound(key) | 返回指向第一个不小于 key 的元素的迭代器 |
upper_bound(key) | 返回指向第一个大于 key 的元素的迭代器 |
equal_range(key) | 返回一个 std::pair,包含 lower_bound 和 upper_bound 的结果 |
int main()
{system("chcp 65001");std::map<std::u8string, int> map1 = {{u8"北京",3},{u8"上海",4},{ u8"广州",5 },{u8"深圳", 6}};auto it = map1.find(u8"北京");if (it != map1.end()){cout << "map1.find()-> , key=" << getStringFromU8string(it->first) << ", value=" << it->second << endl;}cout << "set1.count(2))-> " << map1.count(u8"北京") << endl;cout << "set1.contains(2))-> " << boolalpha << map1.contains(u8"北京") << endl;it = map1.lower_bound(u8"上海");if (it != map1.end()){cout << "set1.lower_bound(2)-> , key=" << getStringFromU8string(it->first) << ", value=" << it->second << endl;}it = map1.upper_bound(u8"广州");if (it != map1.end()){cout << "set1.upper_bound(2)-> , key=" << getStringFromU8string(it->first) << ", value=" << it->second << endl;}auto pair = map1.equal_range(u8"深圳");for (auto it = pair.first; it != pair.second; ++it) {std::cout << "equal_range-> , key=" << getStringFromU8string(it->first) << ", value=" << it->second << endl;}
}
时间复杂度
| 操作 | 时间复杂度 |
|---|
insert / emplace | O(log n) |
erase (键) | O(log n) |
erase (迭代器) | O(1) 摊销 |
find / count / at | O(log n) |
operator[] | O(log n) (可能涉及插入) |
lower_bound / upper_bound | O(log n) |
size / empty | O(1) |
begin / end | O(1) |