STL学习笔记3 —— Association Containers

关联式容器存储元素,往往就是看中了关联式容器可以快速查找、读取或者删除所存储的元素,同时该类型容器插入元素的效率也比序列式容器高。

一、set容器

1. 特点
  • 不再以键值对的方式存储数据,因为 set 容器专门用于存储键和值相等的键值对,因此该容器中真正存储的是各个键值对的值(value)
  • set 容器在存储数据时,会根据各元素值的大小对存储的元素进行排序(默认做升序排序)
  • 存储到 set 容器中的元素,虽然其类型没有明确用 const 修饰,但正常情况下它们的值是无法被修改的(只能用erase、clear修改)
  • set 容器存储的元素必须互不相等

2. 使用

set容器的类模板为:

template < class T,                        // 键 key 和值 value 的类型
           class Compare = less<T>,        // 指定 set 容器内部的排序规则
           class Alloc = allocator<T>      // 指定分配器对象的类型
           > class set;

一般我们只设置第一个参数(存储数据类型的参数)和第二个参数(排序原则),排序原则可以根据需求自定义,默认值为 less<T> 即小的排前面。


set容器的功能函数可以参考 REFERENCE,下面举例使用set

#include <iostream>
#include <set>
using namespace std;

struct mycmp{
	bool operator() (int a, int b){
		return a > b;
	}
}; 

int main()
{
	set<int, mycmp> myset;			// custom order
	set<int, std::greater<int>> s;	// greater first
	s.insert(5);
	s.insert(2);
	s.insert(3);
	s.insert(1);
	s.insert(2);
	s.insert(6);					// repeat 
	
	// size()
	cout << "size = " << s.size() << endl; 
	
	// erase()
	s.erase(6);
	
	// find()
	auto it = s.find(2);
	if (it != s.end()){
		cout << "Successfully!" << endl;
	}
	
	// empty()
	if (s.empty()){
		cout << "The set is empty now." << endl;
	}	
	
	// traverse
	for (auto elem : s){
		cout << elem << " ";
	}
	cout << endl;
	
	// count() 
	cout << "\nElement" << "\t" << "Count" << endl; 
	for (set<int>::iterator it=s.begin(); it!=s.end(); it++){
		cout << *it << "\t" << s.count(*it) << endl; 
	}
	
	return 0;
}

输出结果为:

size = 5
Successfully!
5 3 2 1

Element Count
5       1
3       1
2       1
1       1

其中,结构体 mycmp 的作用是 自定义排序 规则,作为set<>内的参数。mycmp结构体/类的定义方法如下,包含了一个运算符重载,建议使用常引用

struct mycmp{		// 大的排前面(降序)
	bool operator() (const int &a, const int &b){
		return a > b;
	}
}; 

set<int, mycmp> myset;			// custom order
set<int, std::greater<int>> s;	// greater first

对于 自定义的数据类型 ,可以这样子重载运算符:

#include <iostream>
#include <set>
#include <string>
using namespace std;

class Student{
	public:
		string name;
		int number;
		int score;
		Student(string na, int nu, int sc):name(na), number(nu), score(sc){} 
};

struct mycmp{
	bool operator() (const Student &stud1, const Student &stud2){
		return stud1.score < stud2.score;
	}
};

int main()
{
	set<Student> s;
	Student stud1("Lucy", 1, 86);
	Student stud2("Tom", 2, 95); 
	s.insert(stud1);
	s.insert(stud2);
	return 0;
}

若无 mycmp 结构体,则会报错:

In instantiation of ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Student]’:



二、multiset容器

1. 特点

multiset 容器和 set 容器唯一的差别在于,multiset 容器允许存储多个值相同的元素,而 set 容器中只能存储互不相同的元素。

2. 使用
#include <iostream>
#include <set>
using namespace std;

int main()
{
	multiset<int> mymultiset{1, 2, 4, 3, 2, 6};
	mymultiset.insert(5);
	mymultiset.erase(6);
	
	// size()
	cout << "size: " << mymultiset.size() << endl;
	
	// traverse
	cout << endl << "traverse: " << endl;
	for (auto elem : mymultiset){
		cout << elem << " ";
	}
	
	// find()
	cout << "\n\nfind(3)..." << endl;
	if (mymultiset.find(3) != mymultiset.end()){
		cout << "successfully!" << endl;
		cout << "The next element is " << *(mymultiset.find(3)++) << endl;
	}
	
	// count()
	cout << "\nelement" << "\t" << "count" << endl;
	for (auto it=mymultiset.begin(); it!=mymultiset.end(); it++){
		cout << *it << "\t" << mymultiset.count(*it) << endl;
	}
	
	return 0;
}

结果如下:

size: 6

traverse:
1 2 2 3 4 5

find(3)...
successfully!
The next element is 3

element count
1       1
2       2
2       2
3       1
4       1
5       1

--------------------------------
Process exited after 2.543 seconds with return value 0
请按任意键继续. . .


三、map容器

1. 特点
  • 存储 key-value 键值对
  • key 进行排序,key 不允许重复也不能修改
  • 可以通过迭代器访问key-value:it->first, (*it).second
2. 使用

map的 模板 为:

template < class Key,                                     // 指定键(key)的类型
           class T,                                       // 指定值(value)的类型
           class Compare = less<Key>,                     // 指定排序规则
           class Alloc = allocator<pair<const Key,T> >    // 指定分配器对象的类型
           > class map;

map 容器模板有 4 个参数,其中后 2 个参数都设有默认值。大多数场景中,我们只需要设定前 2 个参数的值,有些场景可能会用到第 3 个参数,但最后一个参数几乎不会用到。
下面举例说明定义map、插入键值对、删除键值对、查找、访问等:

#include <iostream>
#include <map>
#include <string>
using namespace std;

int main()
{
	map<int, string> m;
	map<int, string, std::less<int>> m1;		// less order
	map<string, string, greater<string>> m2;	// greater order
	
	m[2] = "banana";							// add items
	m.insert(pair<int, string>(1, "apple"));
	m.insert(make_pair(3, "peach"));
	
	// traverse
	for (auto elem : m){
		cout << elem.first << " " << elem.second << endl;
	}
	cout << endl;
	
	m[2] = "happy";
	// reverse traverse
	map<int, string>::reverse_iterator rit;
	for (rit=m.rbegin(); rit!=m.rend(); rit++){
		cout << rit->first << " " << (*rit).second << endl; 
	}
	
	// find(key)
	auto it = m.find(2);	// return a iterator
	if (it != m.end()){
		cout << "\nThe element with the key 2 is: " << it->second << endl;
	}
	
	cout << m[1] << endl;
	cout << m.at(3) << endl;	// at(key)
	if (!m.empty()){
		cout << "Size: " << m.size() << endl;
	}
	 
	return 0;
}

输出结果为:

1 apple
2 banana
3 peach

3 peach
2 happy
1 apple

The element with the key 2 is: happy
apple
peach
Size: 3

--------------------------------
Process exited after 3.04 seconds with return value 0
请按任意键继续. . .


四、multimap容器

和 map 容器的区别在于,multimap 容器中可以同时存储多(≥2)个键相同的键值对。


参考内容:REFERENCE

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值