【C++】STL关联式容器--set和map

1、键值对

用来表示具有一一对应关系的一种结构。
SGI-STL中对键值对的定义

template <class T1, class T2>
struct pair
{
    typedef T1 first_type;
    typedef T2 second_type;
    T1 first;
    T2 second;
    pair(): first(T1()), second(T2())
    {}
    
    pair(const T1& a, const T2& b): first(a), second(b)
    {}
};

2、set

2.1 set特性

1)set中每个元素都是唯一的,且每个元素不能再容器中修改,但是可以插入或删除它们。

2)set在底层使用的是二叉搜索树(红黑树)实现的。

3)set中的元素不能重复(set有自动去重的功能)

4)set中查找某个元素的时间复杂度:O(logN)

2.2 set

1)set的参数列表

// std::set
template<class T, class Compare = less<T>, class Alloc = allocator<T>>
class set

Compare:默认小于的方式比较
Alloc:set中元素空间的管理方式,使用STL提供的空间配置器

2)set的构造

// 使用(first, last)区间中的元素构造set
set(iterator first, iterator last);

3)set的迭代器

// 正向迭代器
iterator begin();
iterator end();
// 反向迭代器
reverse_iterator rbegin();
reverse_iterator rend();

4)set的容量

bool empty()const;
size_t size() const;

5)修改操作

// 插入
pair<iterator, bool>insert(const T& val);
iterator insert(iterator pos, const T& data);
template<class T>
void insert(T first, T last);

// 删除
void erase(iterator pos);
size_t erase(const T& x); 删除值为x的元素,返回删除的个数
void erase(iterator first, iterator last);删除区间元素

// 交换
void swap(set& x);

// 清空
void clear();

6)operations

iterator find(const T& val) const;

size_t count(const T val)const;

7)set使用代码

#include <iostream>
#include <set>
void TestSet()
{
 	int array[] = { 1, 3, 5, 7, 4, 6, 8, , 4, 6, 8, 0 };
    std::set<int> s(array, array+sizeof(array)/sizeof(array));
    cout << s.size() << endl;
 	// 范围for遍历
    for (auto& e : s)
    	cout << e << " ";
    cout << endl;
 	// 使用迭代器逆向遍历
 	for (auto it = s.rbegin(); it != s.rend(); ++it)
 		cout << *it << " ";
 	cout << endl;
}

 

3、map

3.1 map特性

1)map是关联式容器,它按照一定次序存储键值对的元素。

2)map中按照key进行比较排序

3)可以使用 [] 访问

3.2 map
template < class Key,                                     
           class T,                                       
           class Compare = less<Key>,                     
           class Alloc = allocator<pair<const Key,T>>> 
class map;

1)map构造

std::map();

2)迭代器

iterator begin();
iterator end();
reverse_iterator rbegin();
reverse_iterator rend();

3)容量

bool empty() const;
size_type size() const;

4)元素访问

operator[];
at[]; //C++11

5)修改

// 插入
pair<iterator, bool>insert(const T& val);
iterator insert(iterator pos, const T& val);
template<class T>
void insert(T first, T last);

// 删除
void erase(iterator pos);
size_t erase(const T& k);
void erase(iterator fisrt, iterator last);

// 交换
void swap(map& x);

// 清空
void clear();

6)operations

// 查找
iterator find(const T& k);

size_t count(const T& k) const;

7)map的使用代码

#include <iostream>
#include <string>
#include <map>
void TestMap()
{
    std::map<string, string> m;
    m.insert(std::pair<string, string>("dad", "爸爸"));
    m.insert(std::make_pair("mother", "妈妈"));
    m["son"] = "儿子";
    
    std::cout << m.size() << std::endl;
 
    for (auto& e : m)
 		std::cout << e.first << "-->" << e.second << std::endl;
 	std::cout << endl;

    auto ret = m.insert(std::make_pair("sister", "姐姐"));
    if (ret.second)
    	cout << "sister已经插入" << endl;
    else
 		cout << "sister元素已经存在:" << ret.first->first << "-->" <<ret.first->second <<" 插入失败"<< endl;

 	m.erase("son");
 	if (1 == m.count("son"))
 		cout << "son还在" << endl;
 	else
 		cout << "son被删除" << endl; 
}

8)multimap和multiset中的中的元素是可以重复的

 

4、使用map解决top-K问题

从 arr[1, n] 这 n 个数中,找出最大的k个数(这里的k我给的是3,也可以自己定)。

#include <iostream>
#include <vector>
#include <queue>

class Com
{
public:
	bool operator()(const std::pair<std::string, size_t>& left, const std::pair<std::string, size_t>& right)
	{
		return left.second > right.second;
	}
};

void TestMap()
{
	std::string Fruits[] = { "son", "son", "mom", "mom", "dad", "dad", "sister", "brother", "grandfather", "grandfather", "grandfather", "grandfather", "grandmonther", "grandmonther", "dad", "dad", "dad", "son", "grandson" };

	// 使用map统计英文单词的个数
	std::map<std::string, size_t> m;
	for (auto& e : Fruits)
		++m[e];

	// 建立大顶堆,找到前三个个数最多的英文单词
	std::priority_queue<std::pair<std::string, size_t>, std::vector<std::pair<std::string, size_t>>, Com> p;
	int k = 0;
	for (auto& e : m)
	{
		if (k < 3)
		{
			k++;
			p.push(e);
		}
		else
		{
			if (e.second > p.top().second)
			{
				p.pop();
				p.push(e);
			}
		}
	}

	// 将堆中的元素放在数组中
	std::vector<std::string> vec;
	while(!p.empty())
	{
		vec.push_back(p.top().first);
		p.pop();
	}

	// 打印出出现次数最多的单词
	for (int i = 0; i < 3; ++i)
	{
		std::cout << vec[i] << std::endl;
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值