C++容器map

C++容器map详解


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_boundupper_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;

	// lower_bound
	it = map1.lower_bound(u8"上海");
	if (it != map1.end())
	{
		cout << "set1.lower_bound(2)-> , key=" << getStringFromU8string(it->first) << ", value=" << it->second << endl;
	}

	// upper_bound
	it = map1.upper_bound(u8"广州");
	if (it != map1.end())
	{
		cout << "set1.upper_bound(2)-> , key=" << getStringFromU8string(it->first) << ", value=" << it->second << endl;
	}

	// equal_range
	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 / emplaceO(log n)
erase (键)O(log n)
erase (迭代器)O(1) 摊销
find / count / atO(log n)
operator[]O(log n) (可能涉及插入)
lower_bound / upper_boundO(log n)
size / emptyO(1)
begin / endO(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值