之前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);
}
}
}
}