1、问题
本公司现在要给公司员工发波福利,在员工工作时间会提供大量的水果供员工补充营养。由于水果种类比较多,但是却又不知道
哪种水果比较受欢迎,然后公司就让每个员工报告了自己最爱吃的k种水果,并且告知已经将所有员工喜欢吃的水果存储于一个数组中。
然后让我们统计出所有水果出现的次数,并且求出大家最喜欢吃的前k种水果。
void GetFavoriteFruit(const vector& fruits,size_t k);
ps:要求打印出最喜欢的水果,并且效率尽可能的高。
提示:尽量STL的容器和算法,这样能更快速高效的实现。
2、问题分析:
已知一个vector fruits存放每个员工填写的自己喜欢的k种水果。
(1)首先要遍历该vector,统计出每种水果的数量。可以借助STL容器中的map<水果,水果count>;
(2)排序,找最前k种水果,
<1>用STL中的优先级队列
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <stdlib.h>
//#include <algorithm>
#include <queue>
using namespace std;
void GetFavoriteFruit(const vector<string>& fruits, size_t k)
{
//统计各种水果的个数
map<string, int> fruits_count;
for (int i = 0; i < fruits.size(); ++i)
{
fruits_count[fruits[i]]++;
}
//排序,找最前k种水果
struct Compare //函数对象,堆中的元素比较的方式
{
bool operator()(map<string, int>::iterator it1, map<string, int>::iterator it2)
{
return it1->second < it2->second;
}
};
//优先级队列(大堆),type,container(不能为list),compare,默认是 <
priority_queue<map<string, int>::iterator, vector<map<string, int>::iterator>, Compare> q;
map<string, int>::iterator it = fruits_count.begin();
while (it != fruits_count.end())
{
q.push(it);
++it;
}
for (int i = 0; i < k; ++i)
{
cout <<q.top()->first << " : "<< q.top()->second << endl;
q.pop();
}
}
<2>最大堆
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <stdlib.h>
#include <algorithm>
using namespace std;
//使用堆
void GetFavoriteFruit(const vector<string>& fruits, size_t k)
{
//统计水果数量
map<string, int> fruits_count;
/*原理:map.insert()的返回值是pair<map::iterator,bool>键值对。不管是否插入成功,
它都能返回当前元素的迭代器那么我们可以直接插入,然后对其返回值进行判断,
返回值第二个参数是true,表示插入成功,为flase,表示插入失败*/
pair<map<string, int>::iterator, bool> ret;
for(size_t i = 0; i < fruits.size(); i++)
{
ret = fruits_count.insert(make_pair(fruits[i], 1));
if(ret.second == false)
ret.first->second++;
}
vector<map<string, int>::iterator> v;
map<string, int>::iterator it = fruits_count.begin();
while(it != fruits_count.end())
{
v.push_back(it);
it++;
}
struct Compare
{
bool operator()(map<string, int>::iterator it1, map<string, int>::iterator it2)
{
return it1->second < it2->second;
}
};
make_heap(v.begin(), v.end(),Compare());
//找出大堆中的前k个
vector<map<string, int>::iterator>::iterator iter = v.begin();
for(size_t i = 0; i < k; i++)
{
cout<<(*iter)->first<<" : "<<(*iter)->second<<endl;
pop_heap(v.begin(), v.end(),Compare());
v.pop_back();
}
}
将map存放到vector中进行sort排序,
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <stdlib.h>
#include <algorithm>
using namespace std;
//使用sort排序
void GetFavoriteFruit(const vector<string>& fruits, size_t k)
{
//统计水果数量
map<string, int> fruits_count;
for(size_t i = 0; i < fruits.size(); i++)
{
fruits_count[fruits[i]]++;
}
vector<map<string, int>::iterator> v;
map<string, int>::iterator it = fruits_count.begin();
while(it != fruits_count.end())
{
v.push_back(it);
it++;
}
struct Compare
{
bool operator()(map<string, int>::iterator it1, map<string, int>::iterator it2)
{
return it1->second > it2->second;
}
};
sort(v.begin(), v.end(), Compare());
for(size_t i = 0; i < k; i++)
{
cout<<v[i]->first<<" : "<<v[i]->second<<endl;
}
}
set(也可用来排序,但是会去掉重复,故有缺陷:比如两种水果被选次数相同,会忽略掉一种,打印数量相对更少的)
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <stdlib.h>
#include <vector>
using namespace std;
void GetFavoriteFruit(const vector<string>& fruits, size_t k)
{
//统计各种水果的个数
map<string, int> fruits_count;
for (int i = 0; i < fruits.size(); ++i)
{
fruits_count[fruits[i]]++;
}
struct Compare //函数对象,堆中的元素比较的方式
{
bool operator()(map<string, int>::iterator it1, map<string, int>::iterator it2)
{
return it1->second > it2->second;
}
};
set<map<string, int>::iterator, Compare> s;
map<string, int>::iterator it = fruits_count.begin();
while (it != fruits_count.end())
{
s.insert(it);
++it;
}
//
set<map<string, int>::iterator, Compare>::iterator ite = s.begin();
int count = 0;
while (ite != s.end() && count < k)
{
cout << (*ite)->first << " :" << (*ite)->second << endl;
++ite;
++count;
}
}