【C++】 --如何运用map和set?他们的区别是什么?

前言

我们知道C++的STL库,不只是向我们提供了vector,string,list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和数据结构操作。vector封装了数组,list封装了链表,map和set封装了二叉树,在这些容器中,都会提供基础的操作:增加,删除,排序,查找等。

1、set

map和set都是关联性容器,他的特点是增加或者删除对迭代器的影响都很小,除了操作的节点,对其他节点几乎没什么影响

set是用来存储同一类型的数据,里面的元素都只有一个key值,他支持高效的关键字查询插入操作,比如检查一个关键字是否在set中。如果这个key值之前就存在,那就不进行插入。

以下是关于map和set的常用函数,这里给出插入,查找和删除的方法:
在这里插入图片描述

插入insert:

	set<int> s;
	s.insert(1);
	s.insert(1);
	s.insert(2);
	s.insert(3);
	s.insert(3);
	s.insert(4);
	for (auto e : s)
	{
		cout << e << " ";
		++e;
	}
	cout << endl;
	//或者你可以采用一下输出方式
	//set<int> iterator::it;
	//for(it=s.begin();it!=s.end();it++)
	//{ 
	//		cout<<*it<<" ";
	//}
	//	cout<<endl;
	

运行截图:
在这里插入图片描述
可以看到set的插入操作是排序+去重
查找Find:

set<int>::iterator pos = s.find(3);
	if (pos != s.end())
	{
		cout << "找到啦!"<<endl;
	}

运行截图:
在这里插入图片描述
删除erase:

s.erase(pos);
	cout << "删除后:" << endl;
	for (auto e : s)
	{
		cout << e << " ";
		++e;
	}
	cout << endl;

截图:
在这里插入图片描述
清空clear:

s.clear();
	for (auto e : s)
	{
		cout << e << " ";
		++e;
	}

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

2、map

map和set一样都是关联式容器,他们的底层容器都是红黑树,区别就在于map的值不作为键,键和值是分开的

插入Insert

map<string, string> m;
	m.insert(make_pair("Apple", "苹果"));
	m.insert(make_pair("Pair", "梨"));
	m.insert(make_pair("Right", "右边"));
	//m.insert(make_pair("Right", "正确"));
	m.insert(make_pair("Banana", "香蕉"));
	m.insert(make_pair("Orange", "橘子"));
	m.insert(make_pair("Grap", "葡萄"));

	for(map<string,string>::iterator e=m.begin();e!=m.end();e++)
	{
		cout << e->first << ":" << e->second << endl;
	}
	cout << endl;

查找Find

it = m.find("Banana");
	if (it != m.end())
	{
		cout << "找到了!该单词的中文是:" << it->second << endl;
	}
	else
	{
		cout << "没有找到!";
	}
	cout << endl;

删除erase

m.erase(it);
	cout << "删除刚找到的元素后,剩余的元素为:" << endl;
	map<string, string>::iterator e1;
	for (e1 = m.begin(); e1 != m.end(); e1++)
	{
		cout << e1->first << ":" << e1->second << endl;
	}

3、map和set的区别

set特性如下:

  • set是以RBTree作为底层容器
  • 所得元素的只有key没有value,value就是key
  • 不允许键值重复
  • 所得的元素都会自动排序+去重
  • 不能通过迭代器来改变set的值

map特性如下:

  • map以RBTree作为底层容器
  • 所有的元素都是以键+值存在
  • 不允许键重复
  • 所有元素通过键都会自动排序
  • map的键是不能修改的,但是其键对应的值是可以修改的

关于map和Set的简单应用,这里贴出一个连接,是统计水果出现的次数,并且统计出前topk中最喜欢的水果统计水果次数

4、multiset和multimap

multiset的中文名是多重集合
其实就是集合的扩展版,不同的是在set中,一个值只能出现一次,而在多重集合中,一个值可以出现多次。并且插入和删除一个数都能够在O(logN)的时间内完成,它能够保证序列中的数是有序的。

multimap和map所支持的操作相同(除了multimap不支持下标操作),multimap允许重复的元素。以下是演示multimap的常用接口的代码:

#include <map> 
#include <string> 
#include <iostream> 
using namespace std; 
 
int main() 
{ 
  ///1. 初始化 
  multimap<int, string> mapStudent; 
  multimap<int, string>::iterator iter, beg, end; 
   
  ///2. 添加元素 
  ///multimap不支持下标操作 
  mapStudent.insert(pair<int, string>(0, "student_one")); 
  mapStudent.insert(pair<int, string>(0, "student_one_copy"));///一对多 
  mapStudent.insert(pair<int, string>(1, "student_two")); 
  mapStudent.insert(pair<int, string>(5, "Fear Kubrick")); 
  mapStudent.insert(pair<int, string>(2, "Akemi Homura")); 
  mapStudent.insert(pair<int, string>(-1, "Eren Jaeger")); 
  mapStudent.insert(pair<int, string>(99, "lin")); 
  cout << mapStudent.size() << endl; 
  cout << endl; 
   
  ///3. 遍历 
  for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++) 
    cout << iter->first << " " << iter->second << endl; 
  cout << endl; 
   
  ///4. 单键查询与范围查询 
  ///单键查询 
  int count = mapStudent.count(0); 
  iter = mapStudent.find(0); 
  for (int i = 0; i < count; i++, iter++) 
    cout << iter->first << " " << iter->second << endl; 
  cout << endl; 
  ///范围查询 
  beg = mapStudent.lower_bound(1);/// >=1 
  end = mapStudent.upper_bound(5);/// <=5 
  for (; beg != end; beg++) 
    cout << beg->first << " " << beg->second << endl; 
  cout << endl; 
   
  ///5. 删除 
  iter = mapStudent.find(1); 
  mapStudent.erase(iter); 
  cout << mapStudent.size() << endl; 
  for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++) 
    cout << iter->first << " " << iter->second << endl; 
  cout << endl; 
   
  ///6. 判空与清空 
  if (!mapStudent.empty()) 
    mapStudent.clear(); 
} 

发布了33 篇原创文章 · 获赞 13 · 访问量 1047

猜你喜欢

转载自blog.csdn.net/Vicky_Cr/article/details/104640922