CVTE水果问题

  • 题目:本公司现在要给公司员工发波福利,在员工工作时间会提供大量的水果供员工补充营养。由于水果种类比较多,但是却又不知道哪种水果比较受欢迎,然后公司就让每个员工报告了自己最爱吃的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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值