set和map

1. 键值对

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。 比如一个英汉互译的字典,每个英文单词都对应着一个翻译val。

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

  1. set是按照一定次序存储元素的容器
  2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素
    不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
  3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。
  4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直
    接迭代。
  5. set在底层是用二叉搜索树(红黑树)实现的

注意:1.set中的元素不可以重复(因此可以使用set进行去重)
2.set中的元素不允许修改(因为底层二叉搜索树,修改会改变结构)

2.1 set的使用

set的模板参数列表:
在这里插入图片描述
使用举例:
在这里插入图片描述

3.map的使用介绍

  1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
  2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair: typedef pair value_type;
typedef pair<const Key, T> value_type;
  1. 在内部,map中的元素总是按照键值key进行比较排序的。
  2. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行
    直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
  3. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
  4. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))
    在这里插入图片描述

3.1map的插入

在这里插入图片描述

void testmap()
{
	string strs[] = { "sort", "sort", "insert", "sort", "map", "sort", "map" };
	map<string, int> countMap;
	for (auto& s : strs)
	{
		auto ret = countMap.find(s);
		if (ret != countMap.end())
		{
			ret->second++;
		}
		else
		{
			//countMap.insert(pair<string, int>(s, 1));
			countMap.insert(make_pair(s, 1));
		}
	}

	for (auto& e : strs)
	{
		pair<map<string, int>::iterator, bool> ret = countMap.insert(make_pair(e, 1));

		if (ret.second == false)//插入失败,s已经在map中
		{
			ret.first->second++;
		}
	}

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

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

3.2map的operator[]

在这里插入图片描述

string strs[] = { "sort", "sort", "insert", "sort", "map", "sort", "map" };
	map<string, int> countMap;

	for (auto& s : strs)
	{
		countMap[s]++;
	}

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

在这里插入图片描述

map[]有俩层作用:
1.如果k不在,插入pair(k,v())并且返回value的引用
2.如果k在,不插入,返回和k相等节点额value的引用

4.map的应用

问题描述:本公司现在要给公司员工发波福利,在员工工作时间会提供大量的水果供员工补充营养。由于水果种类
比较多,但是却又不知道哪种水果比较受欢迎,然后公司就让每个员工报告了自己最爱吃的k种水果,并且告知已经将所有员工喜欢吃的水果存储于一个数组中。然后让我们统计出所有水果出现的次数,并且求出大家最喜欢吃的前k种水果

思路:利用map将所有的水果出现的次数统计起来,然后将map的迭代器放入vector之中,最后构造仿函数 ->second进行比较,利用sort进行排序。

void GetFavoriteFruit(const vector<string>& fruits, size_t k)
{ 
	typedef map<string, int>::iterator CountMapIt;
	map<string, int> countMap;
	for (auto& e : fruits)
	{
		countMap[e]++;
	}

	//排序 vector + sort
	vector<CountMapIt> v;
	CountMapIt it = countMap.begin();//将map中迭代器放入数组之中
	while (it != countMap.end())
	{
		v.push_back(it);
		++it;
	}

	//仿函数
	struct CountMapItCompare
	{
		bool operator()(const CountMapIt& it1, const CountMapIt& it2)
		{
			return it1->second > it2->second;
		}
	};

	sort(v.begin(), v.end(), CountMapItCompare());//降序

	for (auto& e : v)
	{
		cout << e->first << ": " << e->second << endl;
		k--;
		if (k == 0)
		{
			break;
		}
	}

}

int main()
{
	const vector<string> v = { "西瓜","香蕉", "西瓜", "葡萄","葡萄","苹果", "葡萄","香蕉", "香蕉", "葡萄","西瓜", "榴莲","西瓜", "榴莲", "苹果", "葡萄", };
	GetFavoriteFruit(v, 3);
	return 0;
}

在这里插入图片描述

692. 前K个高频单词

给一非空的单词列表,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。

class Solution {
public:
    vector<string> topKFrequent(vector<string>& words, int k) {
        //1.用map统计单词出现的频率,map将单词按照ASCII进行了排序
        map<string, int> countMap;
        for(auto& e : words)
        {
            countMap[e]++;
        }

        //2.用multimap对单词出现的频率,排降序
        multimap<int, string, greater<int>> sortMap;//排降序
        for(auto& e : countMap)
        {
            sortMap.insert(make_pair(e.second, e.first));
        }

        vector<string> v;
        auto it = sortMap.begin();
        while(k--)
        {
            v.push_back(it->second);
            it++;
        }

        return v;
    }
};
  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值