【C++】--用map统计水果出现的次数

之前CVTE的笔试题就出现过这样一道题,大致的意思就是统计出水果出现的次数,然后得出前k种员工最喜欢吃的水果。
那这里问题就可以分成两个部分

- 一个是先统计出每种水果出现的次数

这里有三种方法:

//第一种:
void test_map1()
{
	string strs[]={"苹果""香蕉""香蕉","苹果""香蕉""苹果""香蕉""香蕉""草莓"};
	map<string,int> countmap;
	for(auto str:strs)
	{
		auto ret=countmap.find(str);
		if(ret!=countmap.end())
		{
			ret->second++;
		}
		else
		{
			countmap.insert(pair<string,int>(str,1));
		}
	}
}
//第二种方法
void test_map2()
{
	string strs[] = { "苹果","香蕉","香蕉","苹果","香蕉","苹果","香蕉","香蕉","草莓" };
	map<string, int> countmap;
	for (auto str : strs)
	{
		//pair<map<string, int>::iterator, bool> ret = countmap.insert(pair<string, int>(str, 1));
		auto ret= countmap.insert(pair<string, int>(str, 1));  //无论是什么水果都进行插入
		if (ret.second == false)
		{
			ret.first->second++;
		}
	}
}
//第三种方法
void test_map3()
{
	string strs[] = { "苹果","香蕉","香蕉","苹果","香蕉","苹果","香蕉","香蕉","草莓" };
	map<string, int> countmap;
	for (auto str : strs)
	{
		countmap[str]++;
	}
}

前两种方法就很好理解,对于第三种方法主要是重载了“[]”,所以看起来就会有点复杂,函数的原型如下:

mapped_type& operator[] (const key_type&k)
{
	return (*((this->insert(make_pair(k, mapped_type()))).first)).second;
}

可能是不好理解,那我画了一个图,最后返回的是迭代器iterator,那么对它进行解引用,返回的就是迭代器的别名,再取它的second就很容易的得到value的值。
在这里插入图片描述

- 第二步就是一个topk问题
对出现水果的次数进行从大到小排序,取出前 k个元素

struct compare
{
	bool operater()(const pair<string, int>&l, const pair < string, int)&r)
	{
	return l.second > r.second;
	}
};
void test_map3()
{
	string strs[] = { "苹果","香蕉","香蕉","苹果","香蕉","苹果","香蕉","香蕉","草莓" };
	map<string, int> countmap;
	for (auto str : strs)
	{
		countmap[str]++;
	}
	vector<pair<string, int>> v;
	for (auto &e : countmap)
	{
		v.push_back(e);
	}
	sort(v.begin(), b.end(), compare());
	//将结果打印出来
	for (size_t i = 0; i < k; i++)
	{
		cout << v[i].first << ":" << v[i].second << endl;
	}
}
  • 这里再次给出一个优先级队列的解决办法
//利用优先级队列解决
void GetFavoriteFruit(const vector<string>&fruits, size_t k)
{
	//首先统计每种水果的次数
	map<string, int> countmap;
	for (auto &e : fruits)
	{
		countmap[e]++;
	}
   // 排序,先让前k种水果进入队列,然后大于k的在再次比较他们的次数
	priority_queue < pair<string, int>, vector<pair<string, int>, compare>> pq;
	size_t i = 0;
	for (auto e : countmap)
	{
		if (i < k)
		{
			pq.push(e);
			++i;
		}
		else
		{
			if (e.second > pq.top().second)
			{
				pq.pop();
				pq.push(e);
			}
		}
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值