题目:本公司现在要给公司员工发波福利,在员工工作时间会提供大量的水果供员工补充营养。由于水果种类比较多,但是却又不知道哪种水果比较受欢迎,然后公司就让每个员工报告了自己最爱吃的k种水果,并且告知已经将所有员工喜欢吃的水果存储于一个数组中。然后让我们统计出所有水果出现的次数,并且求出大家最喜欢吃的前k种水果。
要求:打印出最喜欢的水果,并且效率尽可能的高。
提示:尽量使用STL的容器和算法,这样能更快速高效的实现。
思路和方法
1.统计所有水果出现的次数
需要同时表示水果和次数两个关键字,我们首先能想到的STL容器就是map和set。采用map统计次数有很多不同的方法。
1)可以采用find方法:找到返回元素的迭代器将其数量加1
没有找到会返回end()就将元素插入进去 //效率低 麻烦2)直接使用insert inset返回一个数据是第一次插入
pair <iterator,bool>
返回false其他返回true此时将数量++
3) 但是直接用[]更加简单//存在会将数量+1//不存在会将元素插入进去非常适合而且效率高简单.统计次数实现代码
map<string, int>m;
for (size_t i = 0; i < v.size(); i++)
{
m[v[i]]++;//存在会将数量+1//不存在会将元素插入进去非常适合而且效率高简单
}
2.出现次数最高的K种水果,我们仍然有多种方法。
1)存进vector里利用sort进行排序
vector<map<string, int>::iterator> vf;
map<string, int>::iterator iter = m.begin();
for (; iter != m.end(); iter++)
{
vf.push_back(iter);
}
sort(vf.begin(), vf.end(), compare());//STL算法需要引入#include<algorithm>
2)将前K个元素创建一个小堆,依次遍历后续的元素,比堆顶元素大则和堆顶元素交换,小则丢弃。
make_heap(vf.begin(), vf.end(), compare());//创建一个堆//默认创建大堆
while (iter != m.end())
{
if (iter->second>vf.front()->second)
{
pop_heap(vf.begin(), vf.end(), compare());//将第一个元素放到最后并调整堆
vf.pop_back();
vf.push_back(iter);
push_heap(vf.begin(), vf.end(), compare());//调用make_heap
}
++iter;
}
for (size_t i = 0; i < K; i++)
{
cout << vf[i]->first.c_str() << ":" << vf[i]->second;
}
cout << endl;
}
3)采用优先级队列
vector<map<string, int>::iterator> vf;
map<string, int>::iterator iter = m.begin();
struct Compare
{
bool operator()(map<string, int>::iterator left, map<string, int>::iterator right)
{
return left->second < right->second;
}
};
priority_queue<map<string, int>::iterator, vector<map<string, int>::iterator>, Compare> q;
while (iter != m.end())
{
q.push(iter);
iter++;
}
for (size_t i = 0; i < K; i++)
{
cout << q.top()->first.c_str() << ":" << q.top()->second;
q.pop();
}
}
- 完整代码
#include<iostream>
#include<stdlib.h>
#include<map>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
//采用map统计次数
//1.可以采用find方法:找到返回元素的迭代器将其数量加1
//:没有找到会返回end()就将元素插入进去//效率低 麻烦
//2.直接使用insert inset返回一个pair<iterator,bool>数据是第一次插入返回false其他返回true此时将数量++
//但是直接用[]更加简单
struct compare
{
bool operator()(map<string, int>::iterator left, map<string, int>::iterator right)
{
return left->second > right->second;
}
};
void GetFaverFruit(vector<string> v)
{
map<string, int>m;
for (size_t i = 0; i < v.size(); i++)
{
m[v[i]]++;//存在会将数量+1//不存在会将元素插入进去非常适合而且效率高简单
}
//1.存进vector里利用sort进行排序
vector<map<string, int>::iterator> vf;
map<string, int>::iterator iter = m.begin();
for (; iter != m.end(); iter++)
{
vf.push_back(iter);
}
sort(vf.begin(), vf.end(), compare());//STL算法需要引入#include<algorithm>
}
/
void GetFaverFruit1(vector<string> v,size_t K)
{
map<string, int>m;
for (size_t i = 0; i < v.size(); i++)
{
m[v[i]]++;
}
vector<map<string, int>::iterator> vf;
map<string, int>::iterator iter = m.begin();
for (size_t i = 0; i < K; i++)
{
vf.push_back(iter);
++iter;
}
make_heap(vf.begin(), vf.end(), compare());//创建一个堆//默认创建大堆
while (iter != m.end())
{
if (iter->second>vf.front()->second)
{
pop_heap(vf.begin(), vf.end(), compare());//将第一个元素放到最后并调整堆
vf.pop_back();
vf.push_back(iter);
push_heap(vf.begin(), vf.end(), compare());//调用make_heap
}
++iter;
}
for (size_t i = 0; i < K; i++)
{
cout << vf[i]->first.c_str() << ":" << vf[i]->second;
}
cout << endl;
}
采用优先级队列进行排序///
void GetFaverFruit2(vector<string> v,size_t K)
{
map<string, int>m;
for (size_t i = 0; i < v.size(); i++)
{
m[v[i]]++;
}
vector<map<string, int>::iterator> vf;
map<string, int>::iterator iter = m.begin();
struct Compare
{
bool operator()(map<string, int>::iterator left, map<string, int>::iterator right)
{
return left->second < right->second;
}
};
priority_queue<map<string, int>::iterator, vector<map<string, int>::iterator>, Compare> q;
while (iter != m.end())
{
q.push(iter);
iter++;
}
for (size_t i = 0; i < K; i++)
{
cout << q.top()->first.c_str() << ":" << q.top()->second;
q.pop();
}
}
int main()
{
vector<string> v;
for (size_t i = 0; i < 8; i++)
{
v.push_back("苹果");
v.push_back("香蕉");
v.push_back("菠萝");
v.push_back("葡萄");
v.push_back("哈密瓜");
v.push_back("梨子");
v.push_back("西瓜");
}
for (size_t i = 0; i < 5; i++)
{
v.push_back("苹果");
v.push_back("香蕉");
v.push_back("菠萝");
}
for (size_t i = 0; i < 2; i++)
{
v.push_back("菠萝");
v.push_back("葡萄");
v.push_back("哈密瓜");
}
for (size_t i = 0; i < 3; i++)
{
v.push_back("苹果");
v.push_back("西瓜");
v.push_back("哈密瓜");
}
GetFaverFruit2(v,5);
system("pause");
return 0;
}