【C++之容器篇】map和set常见函数接口的使用与剖析

news2024/12/29 17:18:14

目录

    • 前言
    • 一、set
      • 1. 简介
      • 2. 成员类型
      • 3. 构造函数
        • (1) set()
        • (2)set(InputIterator first,InputIterator last)
        • (3)使用
      • 4. 拷贝构造函数和赋值运算符重载
      • 5. empty()
      • 6. size()
      • 7. insert()
        • (1)pair<iterator,bool> insert(const K& key)
        • (2)iterator insert(iterator pos,const K& key)
        • (3)void insert(InputIterator first,InputIterator last)
        • (4)综合测试set的插入接口
      • 8. erase()
        • (1)void erase(iterator pos)
        • (2)size_t erase(const K& key)
        • (3)void erase(iterator first,iterator last)
        • (4)综合测试set中的删除函数接口
      • 9.swap()
      • 10. clear()
      • 11. find()
      • 12.count()
      • 13. set<K>::iterator lower_bound(const K& key)
      • 14. set<int>::iterator upper_bound(const K& key)
    • 二、map
      • 1. 简介
      • 2. 成员类型
      • 3. 构造函数
      • 4. pair
      • 5. make_pair()
      • 5. 拷贝构造函数和赋值运算符重载函数
      • 6. empty()
      • 7. size()
      • 8. operator[]
      • 9. insert()
      • 10. erase()
        • (1) void erase(iterator pos)
        • (2) size_t erase(const K& key)
        • (3) void erase(iterator first,iterator last)
        • (4) 综合测试erase的所有接口
      • 11. swap()
      • 12. clear()
      • 13. find()
      • 14. count()
      • 15.lower_bound()
      • 16.upper_bound()

前言

map和set是数据结构中非常常用的结构,这两个结构都属于二叉搜索树,set中的结点存储的是关键字,map中的结点存储的是键值对。set和map都只支持存储唯一一个关键字,不允许关键字冗余,但是其衍生出来的multiset和multimap数据结构就支持存储多个关键子,下面将通过实际代码来详细介绍这两类数据结构的使用。

一、set

1. 简介

在这里插入图片描述

2. 成员类型

在这里插入图片描述

3. 构造函数

在这里插入图片描述

(1) set()

这个构造函数是一个无参的构造函数,是最常用的一个构造函数,其使用和之前学习的数据结构一样

(2)set(InputIterator first,InputIterator last)

这个构造函数是支持使用一段迭代器区间进行初始化,传迭代器区间的时候同样需要注意,传的必须是左闭右开的区间。

(3)使用

  • 代码:
void test_set1()
{
	// 使用set的构造函数
	//无参构造函数
	set<int> s1;
	set<string> s2;
	set<vector<int>> s3;

	// 使用一段迭代器区间进行构造
	string str("hello set(InputIterator first, InputIterator last)");
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	set<char> s4(str.begin(), str.end());
	set<int> s5(v.begin(), v.end());

	// 遍历set
	cout << "s1:" << endl;
	set<int>::iterator sit1 = s1.begin();
	while (sit1 != s1.end())
	{
		cout << *sit1 << " ";
		sit1++;
	}
	cout << endl;

	cout << "s2:" << endl;
	set<string>::iterator sit2 = s2.begin();
	while (sit2 != s2.end())
	{
		cout << *sit2 << " ";
		sit2++;
	}
	cout << endl;

	cout << "s4:" << endl;
	set<char>::iterator sit4 = s4.begin();
	while (sit4 != s4.end())
	{
		cout << *sit4 << " ";
		sit4++;
	}
	cout << endl;

	cout << "s5:" << endl;
	set<int>::iterator sit5 = s5.begin();
	while (sit5 != s5.end())
	{
		cout << *sit5 << " ";
		sit5++;
	}
	cout << endl;

}

运行结果:
在这里插入图片描述

4. 拷贝构造函数和赋值运算符重载

在这里插入图片描述
在这里插入图片描述

  • 代码:
void test_set2()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);

	set<int> s1(v.begin(), v.end());
	set<int> s2 = s1;// 调用拷贝构造函数
	set<int> s3;
	s3 = s2;// 调用赋值运算符重载函数
	cout << "s1:" << endl;
	for (auto& e : s1)
	{
		cout << e << " ";
	}
	cout << endl;

	cout << "s2:" << endl;
	for (auto& e : s2)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << "s3:" << endl;
	for (auto& e : s3)
	{
		cout << e << " ";
	}
	cout << endl;

}

运行结果:
在这里插入图片描述

5. empty()

这个函数的功能就是判断set是否为空,如果为空,则返回true,否则返回false
在这里插入图片描述

6. size()

这个函数是求set中结点的个数的
在这里插入图片描述

  • 代码:
void test_set3()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);

	set<int> s1(v.begin(), v.end());
	cout << "s1:" << endl;
	for (auto& e : s1)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << "s1中的结点个数为:" << s1.size() << endl;
}

运行结果:
在这里插入图片描述

7. insert()

在这里插入图片描述

(1)pair<iterator,bool> insert(const K& key)

这个函数支持向set中插入一个key,插入之后会返回一个键值对,键值对其实本质就是一个结构体,其中存储两个值,分别叫做first和second,其中的first是iterator,也就是指向插入结点的迭代器,second是bool,标识插入是否成功,当插入的key在set中是存在的,则插入失败,返回的键值对中的迭代器指向这个已经存在的值,键值对中的bool值为false,如果插入的key不存在,则返回的键值对中的迭代器指向新插入的结点,bool值为true。

(2)iterator insert(iterator pos,const K& key)

这个函数支持在pos位置处插入一个key,返回插入位置的迭代器,这个接口平时很少用,也不太能用,因为值不能随便向set中进行插入,很容易会破坏set的结构。

(3)void insert(InputIterator first,InputIterator last)

这个函数支持向set中插入一段迭代器区间,没有返回值

(4)综合测试set的插入接口

  • 代码:
void test_set4()
{
	// 测试set的插入函数
	set<int> s;
	pair<set<int>::iterator,bool> p1 = s.insert(1);
	cout << *(p1.first) << endl;
	pair<set<int>::iterator, bool> p2 = s.insert(3);
	cout << *(p2.first) << endl;

	pair<set<int>::iterator, bool> p3 = s.insert(2);
	cout << *(p3.first) << endl;

	pair<set<int>::iterator, bool> p4 = s.insert(6);
	cout << *(p4.first) << endl;

	pair<set<int>::iterator, bool> p5 = s.insert(4);
	cout << *(p5.first) << endl;

	pair<set<int>::iterator, bool> p6 = s.insert(8);
	cout << *(p6.first) << endl;


	for (auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl;

	// 在3位置处插入30
	set<int>::iterator pos = s.find(3);
	if (pos != s.end())
	{
		// 找到了
		set<int>::iterator pos1 = s.insert(pos, 30);
		cout << *pos1 << endl;
	}
	else
	{
		// 找不到
		cout << "没有找到此值" << endl;
	}

	// 构造一个vector
	vector<int> v = { 10,7,5,40,50 };
	// 向s 插入一段迭代器区间
	s.insert(v.begin(), v.end());
	for (auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl;

}

运行结果:
在这里插入图片描述

8. erase()

在这里插入图片描述

(1)void erase(iterator pos)

这个接口支持删除某个位置的值,需要提供删除值的位置(迭代器)

(2)size_t erase(const K& key)

这个接口支持删除set中的某一个值为key的结点,需要提供删除的key

(3)void erase(iterator first,iterator last)

这个接口支持删除set中的某一段连续的值

(4)综合测试set中的删除函数接口

  • 代码
void test_set5()
{
	//测试set中的删除函数
	set<int> s;
	s.insert(10);
	s.insert(4);
	s.insert(6);
	s.insert(2);
	s.insert(8);
	s.insert(5);
	s.insert(1);

	for (auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl;

	// 删除某一个位置的迭代器
	// 先通过find去获取这个值的迭代器
	set<int>::iterator pos = s.find(4);
	if (pos != s.end())
	{
		// 找到了
		s.erase(pos);
	}

	for (auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl;

	// 删除某一个值
	s.erase(10);
	for (auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl;

	// 删除某一段区间
	s.erase(s.begin(), s.end());
	for (auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl;
	
}

运行结果:
在这里插入图片描述

9.swap()

这个函数支持交换两个set对象的内容
在这里插入图片描述

  • 代码:
void test_set6()
{
	// 测试交换函数
	set<int> s1;
	s1.insert(1);
	s1.insert(6);
	s1.insert(5);
	s1.insert(4);
	s1.insert(3);
	s1.insert(2);
	cout << "s1:" << endl;
	for (auto& e : s1)
	{
		cout << e << " ";
	}
	cout << endl;

	set<int> s2;
	s2.insert(10);
	s2.insert(9);
	s2.insert(8);
	s2.insert(7);
	s2.insert(6);
	s2.insert(15);
	cout << "s2:" << endl;
	for (auto& e : s2)
	{
		cout << e << " ";
	}
	cout << endl;

	s1.swap(s2);
	cout << "swap s1 and s2:" << endl;
	cout << "s1:" << endl;
	for (auto& e : s1)
	{
		cout << e << " ";
	}
	cout << endl;

	cout << "s2:" << endl;
	for (auto& e : s2)
	{
		cout << e << " ";
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

10. clear()

在这里插入图片描述
这个函数的功能是将set中的所有结点删除

void test_set7()
{
	// 测试交换函数
	set<int> s1;
	s1.insert(1);
	s1.insert(6);
	s1.insert(5);
	s1.insert(4);
	s1.insert(3);
	s1.insert(2);
	cout << "s1:" << endl;
	for (auto& e : s1)
	{
		cout << e << " ";
	}
	cout << endl;
	s1.clear();
	cout << "s1:" << endl;
	for (auto& e : s1)
	{
		cout << e << " ";
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

11. find()

在这里插入图片描述
这个函数是支持在set中查找一个值,如果找到,则返回这个结点的迭代器,否则返回end()。这个find接口需要和算法中的find进行区分,set中的find函数是根据搜索树的性质进行查找的,而算法中的find是进行暴力查找的,所以这两者的查找效率是不一样的。

void test_set8()
{
	//测试set中的find
	vector<int> v = { 3,4,7,5,1,9,8 };
	set<int> s(v.begin(),v.end());
	set<int>::iterator pos;
	for (auto& e : v)
	{
		pos = s.find(e);
		if (pos != s.end())
		{
			// 找到了
			cout << *pos << endl;
		}
		else
		{
			// 找不到
			cout << "找不到此值" << endl;
		}
	}
}

运行结果:
在这里插入图片描述

12.count()

在这里插入图片描述

这个函数的作用是求set中对应结点的个数,理论上set中的每一个结点在set中只能出现,所以查找的值返回的值次数理论上只能是1或者0。所以在set中,count()函数也能充当查找的功能。

void test_set9()
{
	//测试set中的find
	vector<int> v = { 3,4,7,5,1,9,8 };
	set<int> s(v.begin(), v.end());
	set<int>::iterator pos;
	for (auto& e : v)
	{
		cout << s.count(e) << " ";
	}
	cout << endl;
	vector<int> v1 = { 1,2,3,4,5,6,7,8,9 };
	for (auto& e: v1)
	{
		cout << e << "出现的次数:" << s.count(e) << endl;
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

13. set::iterator lower_bound(const K& key)

在这里插入图片描述
这个函数的功能是返回比key大或者相等的结点的迭代器

void test_set10()
{
	// 测试lower_bound
	vector<int> v = { 3,4,7,5,1,9,8 };
	set<int> s(v.begin(), v.end());
	// 找的值在set中存在
	set<int>::iterator lowIt = s.lower_bound(4);
	if (lowIt != s.end())
	{
		cout << *lowIt << endl;
	}
	else
	{
		cout << "找不到" << endl;
	}
	// 找的值在set中不存在
	lowIt = s.lower_bound(6);
	if (lowIt != s.end())
	{
		cout << *lowIt << endl;
	}
	else
	{
		cout << "找不到" << endl;
	}
}

运行结果:
在这里插入图片描述

14. set::iterator upper_bound(const K& key)

在这里插入图片描述
这个函数的功能是返回比key大的结点的迭代器(不包含key的结点)

void test_set11()
{
	// 测试upper_bound
	vector<int> v = { 3,4,7,5,1,9,8 };
	set<int> s(v.begin(), v.end());
	// 找的值在set中存在
	set<int>::iterator lowIt = s.upper_bound(4);
	if (lowIt != s.end())
	{
		cout << *lowIt << endl;
	}
	else
	{
		cout << "找不到" << endl;
	}
	// 找的值在set中不存在
	lowIt = s.upper_bound(6);
	if (lowIt != s.end())
	{
		cout << *lowIt << endl;
	}
	else
	{
		cout << "找不到" << endl;
	}
}

运行结果:
在这里插入图片描述

  • lowerbound()和upper_bound()的综合使用场景
    可以和set.erase(InputIterator first,InputIterator last)这个函数接口进行使用,删除一段迭代器区间
    代码:
void test_set12()
{
	// 综合测试lower_bound()和upper_bound()的使用
	vector<int> v = { 2,3,5,1,7,6,4,9,8,10 };
	set<int> s(v.begin(), v.end());

	for (auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl;

	//删除1-6的值
	set<int>::iterator lowIt = s.lower_bound(1);
	set<int>::iterator upIt = s.upper_bound(6);
	s.erase(lowIt, upIt);
	for (auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

二、map

1. 简介

在这里插入图片描述

2. 成员类型

在这里插入图片描述

3. 构造函数

在这里插入图片描述
这个构造函数中比较常用的是使用无参构造函数进行创建对象


void test_map1()
{
	// 无参构造函数
	map<int, int> m1;
	map<string, string> m2;
	map<string, int> m3;
	map<vector<int>, vector<int>> m4;
}

4. pair

pair是键值对的意思,其本质是一个结构体,其中包含两个成员变量firstsecond,使用pair的时候需要注意包头文件
在这里插入图片描述

// pair
template <class K,class V>
struct pair
{
	K first;
	V second;
};

5. make_pair()

在这里插入图片描述
make_pair本质上是一个函数调用,就算将两个类型的值传给make_pair()然后构造出一个pair类型出来
其中需要注意,我们在传pair类型的参数的时候,是需要指明模板参数的,但是使用make_pair的时候是不需要指明模板参数的,后面的场景将会遇到

5. 拷贝构造函数和赋值运算符重载函数

使用方法和之前学习的数据结构一模一样。

void test_map14()
{
	// 使用拷贝构造函数和赋值运算符重载函数
	map<int, int> m;
	m[1] = 1;
	m[2] = 2;
	m[3] = 3;
	m[4] = 4;
	m[5] = 5;
	m[6] = 6;
	m[7] = 7;

	map<int, int> m1 = m;// 调用拷贝构造函数
	map<int, int> m2;
	m2 = m1;// 调用赋值运算符重载函数

	cout << "m:" << endl;
	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	cout << "m1:" << endl;
	for (auto& e : m1)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	cout << "m2:" << endl;
	for (auto& e : m2)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

6. empty()

在这里插入图片描述
判断map是否为空,如果为空,返回true,否则,返回false

void test_map10()
{
	//测试empty()

	map<int, int> m;
	m.insert(make_pair(1, 1));
	m.insert(make_pair(2, 1));
	m.insert(make_pair(3, 1));
	m.insert(make_pair(4, 1));
	m.insert(make_pair(5, 1));
	m.insert(make_pair(6, 1));
	m.insert(make_pair(7, 1));
	m.insert(make_pair(8, 1));
	m.insert(make_pair(9, 1));

	if (m.empty())
	{
		cout << "该树为空" << endl;
	}
	else
	{
		cout << "该树不为空" << endl;
	}

	m.clear();
	if (m.empty())
	{
		cout << "该树为空" << endl;
	}
	else
	{
		cout << "该树不为空" << endl;
	}

}

运行结果:
在这里插入图片描述

7. size()

返回map中结点的个数
在这里插入图片描述

void test_map11()
{
	// 测试size()
	map<int, int> m;
	m.insert(make_pair(1, 1));
	m.insert(make_pair(2, 1));
	m.insert(make_pair(3, 1));
	m.insert(make_pair(4, 1));
	m.insert(make_pair(5, 1));
	m.insert(make_pair(6, 1));
	m.insert(make_pair(7, 1));
	m.insert(make_pair(8, 1));
	m.insert(make_pair(9, 1));

	cout << "该树的结点为" << m.size() << endl;
	m.clear();
	cout << "该树的结点为" << m.size() << endl;

}

运行结果:
在这里插入图片描述

8. operator[]

在这里插入图片描述
这个函数需要中单关注其返回值,其返回值是一个mapped_type&类型,也就是value的引用,所以返回值是支持修改的,其中涉及的插入过程中的细节在insert()中会进行细讲。
综上,我们可以知道,operator[]()充当的作用可以是插入,也可以是修改,也可以是仅仅访问某一个结点中的值

  • 代码1:插入+访问
void test_map12()
{
	// 测试[]
	map<int, int> m;
	m[1] = 1;
	m[2] = 2;
	m[3] = 3;
	m[4] = 4;
	m[5] = 5;
	m[6] = 6;
	m[7] = 7;

	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

}

运行结果:
在这里插入图片描述

  • 代码2:插入+访问+修改
void test_map13()
{
	// 测试[]
	map<int, int> m;
	m[1] = 1;
	m[2] = 2;
	m[3] = 3;
	m[4] = 4;
	m[5] = 5;
	m[6] = 6;
	m[7] = 7;

	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	m[1] = 11;
	m[2] = 22;

	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

9. insert()

在这里插入图片描述
上面的接口中最常用的是插入pair类型的,这个函数需要中单关注其返回值,其返回值是一个pair<iterator,bool>类型,operator[]() 函数首先会调用 insert()函数,如果插入的值存在,则返回的pair<iterator,bool>中的iterator指向的是这个存在的结点,bool为false,表示此次插入失败,如果插入的值不存在,则成功插入,返回的pair<iterator,bool>中的iterator指向这个新插入的迭代器,bool为true,表示此次插入是成功的。
综上,我们可以知道,operator[]()充当的作用可以是插入,也可以是修改,也可以是仅仅访问某一个结点中的值使用如下:

void test_map2()
{
	// std::pair<iterator,bool> set::insert(make_pair(key,value));
	map<string, string> m1;
	m1.insert(std::pair<string, string>("string", "字符串"));
	m1.insert(make_pair("sort", "排序"));
	m1.insert(make_pair("left", "左边"));

	for (auto& e : m1)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

10. erase()

在这里插入图片描述

(1) void erase(iterator pos)

这个接口是支持给定迭代器,删除迭代器位置处的结点

(2) size_t erase(const K& key)

这个接口是支持删除给定的key的结点

(3) void erase(iterator first,iterator last)

这个接口支持删除一段迭代器区间,一般可以和lower_bound()和upper_bound()进行使用

(4) 综合测试erase的所有接口

  • 代码:
void test_map3()
{
	map<string, string> m;
	m.insert(make_pair("string", "字符串"));
	m.insert(make_pair("left", "左边"));
	m.insert(make_pair("apple", "苹果"));
	m.insert(make_pair("insert", "插入"));
	m.insert(make_pair("erase", "删除"));

	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	// 删除erase:支持通过key进行删除
	m.erase("erase");

	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	// 删除insert:通过iterator 进行删除
	// 找到insert的迭代器
	map<string, string>::iterator pos = m.find("insert");
	if (pos != m.end())
	{
		// 找到了
		m.erase(pos);
	}
	else
	{
		// 找不到
		cout << "找不到" << endl;
	}

	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	// 删除全部的结点:使用迭代器区间进行删除
	m.erase(m.begin(), m.end());

	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

}

运行结果:
在这里插入图片描述

11. swap()

在这里插入图片描述
这个交换函数的底层是交换两个map中的根节点指针,std中的交换函数实现的是深拷贝,这个要区分开来。

void test_map4()
{
	// 测试交换函数
	map<string, string> m;
	m.insert(make_pair("string", "字符串"));
	m.insert(make_pair("left", "左边"));
	m.insert(make_pair("apple", "苹果"));
	m.insert(make_pair("insert", "插入"));
	m.insert(make_pair("erase", "删除"));

	map<string, string> m1;
	m1.insert(std::pair<string, string>("string", "字符串"));
	m1.insert(make_pair("sort", "排序"));
	m1.insert(make_pair("left", "左边"));

	cout << "m:" << endl;
	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	cout << "m1:" << endl;
	for (auto& e : m1)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	m1.swap(m);
	cout << "m:" << endl;
	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	cout << "m1:" << endl;
	for (auto& e : m1)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

12. clear()

在这里插入图片描述
这个函数的功能是完成map中结点资源的清理

void test_map5()
{
	// 测试clear
	map<string, string> m;
	m.insert(make_pair("string", "字符串"));
	m.insert(make_pair("left", "左边"));
	m.insert(make_pair("apple", "苹果"));
	m.insert(make_pair("insert", "插入"));
	m.insert(make_pair("erase", "删除"));

	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	m.clear();
	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

13. find()

在这里插入图片描述
这个函数的功能是通过key去找迭代器,所以find函数返回的是找的结点的迭代器,如果找到,返回找的结点的迭代器,否则,返回end()

void test_map6()
{
	map<string, string> m;
	m.insert(make_pair("string", "字符串"));
	m.insert(make_pair("left", "左边"));
	m.insert(make_pair("apple", "苹果"));
	m.insert(make_pair("insert", "插入"));
	m.insert(make_pair("erase", "删除"));

	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	map<string, string>::iterator pos = m.find("apple");
	if (pos != m.end())
	{
		// 找到了
		cout << pos->first << ":" << pos->second << endl;
	}
	else
	{
		// 找不到
		cout << "找不到" << endl;
	}
}

运行结果:
在这里插入图片描述

14. count()

计算map中结点出现的个数,理论上对于map,因为map中的数据不能出现冗余,所以map中count的返回值只可能是0或者1

15.lower_bound()

在这里插入图片描述
通过key,调用lower_bound()函数返回大于等于key的结点的迭代器

void test_map7()
{
	// 测试lower_bound()
	map<int, int> m;
	m.insert(make_pair(1, 1));
	m.insert(make_pair(2, 1));
	m.insert(make_pair(3, 1));
	m.insert(make_pair(4, 1));
	m.insert(make_pair(5, 1));
	m.insert(make_pair(6, 1));
	// map中存在的值
	map<int, int>::iterator lowIt = m.lower_bound(2);
	if (lowIt != m.end())
	{
		// 找到了
		cout << lowIt->first << ":" << lowIt->second << endl;
	}
	else
	{
		// 找不到
		cout << "找不到" << endl;
	}
	// map中不存在的值
	lowIt = m.lower_bound(0);
	if (lowIt != m.end())
	{
		// 找到了
		cout << lowIt->first << ":" << lowIt->second << endl;
	}
	else
	{
		// 找不到
		cout << "找不到" << endl;
	}

}

运行结果:
在这里插入图片描述

16.upper_bound()

在这里插入图片描述
通过key,调用lower_bound()函数返回大于key的结点的迭代器

void test_map8()
{
	// 测试upper_bound()
	map<int, int> m;
	m.insert(make_pair(1, 1));
	m.insert(make_pair(2, 1));
	m.insert(make_pair(3, 1));
	m.insert(make_pair(4, 1));
	m.insert(make_pair(5, 1));
	m.insert(make_pair(6, 1));
	// map中存在的值
	map<int, int>::iterator upIt = m.upper_bound(2);
	if (upIt != m.end())
	{
		// 找到了
		cout << upIt->first << ":" << upIt->second << endl;
	}
	else
	{
		// 找不到
		cout << "找不到" << endl;
	}
	// map中不存在的值
	upIt = m.upper_bound(0);
	if (upIt != m.end())
	{
		// 找到了
		cout << upIt->first << ":" << upIt->second << endl;
	}
	else
	{
		// 找不到
		cout << "找不到" << endl;
	}

}

运行结果:
在这里插入图片描述

  • 综合使用lower_bound()和upper_bound()
void test_map9()
{
	map<int, int> m;
	m.insert(make_pair(1, 1));
	m.insert(make_pair(2, 1));
	m.insert(make_pair(3, 1));
	m.insert(make_pair(4, 1));
	m.insert(make_pair(5, 1));
	m.insert(make_pair(6, 1));
	m.insert(make_pair(7, 1));
	m.insert(make_pair(8, 1));
	m.insert(make_pair(9, 1));

	// 删除前遍历一次
	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	// 要求删除1-4的值
	map<int, int>::iterator lowIt = m.lower_bound(1);
	map<int, int>::iterator upIt = m.upper_bound(4);

	// 调用erase()
	m.erase(lowIt, upIt);
	// 删除后遍历一次
	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/353987.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零信任-Cisco思科零信任介绍(10)

​目录 ​思科零信任介绍 思科零信任所涉及产品 思科零信任架构拓扑介绍 ​思科零信任框架VS零信任安全框架 思科零信任架构的应用场景 思科零信任解决方案的优势 思科零信任的未来发展展望 思科零信任介绍 Cisco Zero Trust是思科公司推广的一种安全模型&#xff0c;旨…

实现qq群消息接收和发送功能

QQWebsocketClient是什么 实现qq群消息接收和发送功能&#xff0c;基于websocket技术和cqhttp服务开发 一、 效果截图 二、实现思路 使用cqhttp进行socket反向代理&#xff0c;获取qq聊天的所有消息 编写java客户端&#xff0c;连接至cqhttp服务器获取聊天消息 获取聊天消…

spring boot 自动配置类,详细过程

springboot version(v2.7.8)启动类SpringBootApplication public class SecurityApplication { public static void main(String[] args) {SpringApplication.run(SecurityApplication.class, args);} }1 点击 SpringBootApplication进入&#xff0c;EnableAutoConfiguration 开…

把Typora图片自动上传网

闲话少说 总共三步下载PicGohttps://github.com/Molunerfinn/PicGo/releases/download/v2.3.1/PicGo-Setup-2.3.1-x64.exe直接点就行这里略过Gitee我们需要使用 Git 来保存我们的图片&#xff0c;又因为国内访问 Github 速度比较慢&#xff0c;所以这里推荐使用国内的 Git 托管…

Blazor入门100天 : 身份验证和授权 (1) - 建立带身份验证工程

目录 建立默认带身份验证 Blazor 程序角色/组件/特性/过程逻辑DB 改 Sqlite将自定义字段添加到用户表脚手架拉取IDS文件,本地化资源freesql 生成实体类,freesql 管理ids数据表初始化 Roles,freesql 外键 > 导航属性完善 freesql 和 bb 特性 知识点 Microsoft.AspNetCore.…

数据结构与算法之数组寻找峰值分而治之

这一篇分享一道在数组中寻找峰值的题目&#xff0c;使用到分而治之&#xff0c;二分查找等思想。本文章会讲解这个二分查找的本质&#xff0c;以及为什么要用二分查找&#xff0c;它能解决哪一类题目&#xff1f;目录&#xff1a;一.题目及其要求1.分而治之2.题目思路3.具体做法…

渗透测试实战 - 外网渗透内网穿透(超详细)

文章目录实验环境Target1 - Centos7 &#xff08;web服务&#xff09;Target2 - Ubuntu &#xff08;内网web服务&#xff09;Target3 - Windows7 (客户端)实验目的实验步骤测试Target1信息收集22/21端口 弱口令爆破(MSF&#xff0c;hydra)3306端口8888端口80端口主机信息收集反…

在AWS Glue上使用JDBC连接Trino

呼应此前一篇文章《在Spark上使用JDBC连接Trino》&#xff0c;继续在AWS Glue上测试JDBC连接Trino&#xff0c;同样&#xff0c;这是一个非常不典型的应用用场景&#xff0c;本文仅记录测试步骤和结果&#xff0c;不做评论。本文地址&#xff1a;https://laurence.blog.csdn.ne…

还在想假期去哪玩?直接做一个旅游攻略小程序

憋了几年好不容易解封准备出去散散心,但看着大江南北这么多景点是不是有点让你选择强迫症呢?那就先制作一个旅游攻略小程序看看驴友们的分享吧。

E. Explosions?(思维+单调队列

Problem - E - Codeforces 题意&#xff1a;有 n 个怪&#xff0c;生命值为&#xff0c;你有两种操作&#xff0c;一种花费 1 MP减少一个怪的一格血量&#xff0c;可以操作任意次&#xff1b;另一次是花费 x MP&#xff0c;制造一个爆炸&#xff0c;可以不断消灭两侧连续严格递…

【C语言】 详谈指针

☃️内容专栏&#xff1a;【C语言】初阶部分 ☃️本文概括&#xff1a;继初识C语言&#xff0c;对C语言指针初阶部分进行归纳与总结。 ☃️本文作者&#xff1a;花香碟自来_ ☃️发布时间&#xff1a;2023.2.17 目录 一、指针和指针类型 1.1 指针 1.2 指针类型 其一&#x…

运动耳机选择什么模式?运动耳机的正确选择

动是生命的源泉&#xff0c;有许多朋友都会在运动的时候戴上一个运动耳机。因为运动时听音乐会给我们带来充足的动力&#xff0c;但是选择一款合适自己的运动耳机也是一门学问&#xff0c;今天我就来给大家推荐几款还不错的运动耳机。 1、NANK南卡RunnerPro4骨传导运动耳机 骨…

下载网上压缩包(包含多行json)并将其转换为字典的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…

分布式 CAP BASE理论

文章目录CAP简介不是所谓的“3 选 2”CAP 实际应用案例BASE简介BASE 理论的核心思想总结CAP 简介 在理论计算机科学中&#xff0c;CAP 定理&#xff08;CAP theorem&#xff09;指出对于一个分布式系统来说&#xff0c;当设计读写操作时&#xff0c;只能同时满足以下三点中的…

cesium学习记录01

1&#xff0c;将右弦GISer的cesium实战系列的大部分功能&#xff08;25-110&#xff09; 都又跟着走了一遍&#xff08;大部分是CTRL CCRTL V&#xff09; 2&#xff0c;代码SVN地址&#xff08;用户名:liu 密码&#xff1a;123&#xff09; 主要文件是test/src/views/MapFu…

Prometheus离线tar包安装

Prometheus离线tar包安装实验环境一、部署前操作二、Master2.1下载2.2解压2.3更改服务目录名称2.4创建系统服务启动文件2.5配置修改2.6启动并设置开机自启2.7访问2.8添加node节点2.8.1 添加方法2.8.2修改Prometheus配置&#xff08;Master&#xff09;————————————…

docker:实例演示妙用export让容器和数据分离

简介&#xff1a;docker-export用于将容器打包成基础镜像&#xff0c;主要作用就是制作基础镜像&#xff0c;特别是在容器非常大的情况下&#xff0c;拉取了一个空白系统镜像&#xff0c;创建容器后安装了一堆自己需要的环境&#xff0c;就可以使用 export 命令打包成自己的基础…

2005-2022中国企业对外直接投资、OFDI海外投资明细、中国全球投资追踪数据CGIT(含非建筑施工类问题投资)

中国全球投资跟踪”&#xff08;China Global Investment Tracker&#xff09;&#xff0c;数据库&#xff0c;美国企业研究所于1月28日发布。数据库显示&#xff0c;2005年以来&#xff0c;中国对外投资和建设总额已接近2万亿美元。该数据库是唯一一套涵盖中国全球投资和建设的…

概率和似然

在日常生活中&#xff0c;我们经常使用这些术语。但是在统计学和机器学习上下文中使用时&#xff0c;有一个本质的区别。本文将用理论和例子来解释概率和似然之间的关键区别。 概率与似然 假设在一场棒球比赛中&#xff0c;两队的队长都被召集到场上掷硬币。获胜的队长将根据掷…

Linux 监测服务心跳、服务重启策略

文章目录前言背景一、curl服务可用验证二、服务探测脚本三、配置系统定时任务四、Linux特殊字符转义总结前言 请各大网友尊重本人原创知识分享&#xff0c;谨记本人博客&#xff1a;南国以南i、 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 背景 当…