面试题:找出公司员工最喜欢的k种水果

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;
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 数仓分层理论是数据仓库设计中的一个重要概念。根据数据仓库的目标和使用需求,数据仓库可以划分为不同的层次。常见的数仓分层理论包括三层架构和四层架构。 三层架构包括原子层、集成层和应用层。原子层是数据仓库中最底层的层次,负责采集和存储原始数据。集成层是在原子层的基础上进行数据清洗、整合和转换,使得数据能够被应用层使用。应用层是最上层的层次,提供给用户各报表、分析和决策支持的功能。 四层架构在三层架构的基础上增加了数据存储层。数据存储层是为了提高数据查询和分析的性能而引入的,通常使用列式存储或者索引技术来优化数据的存储和访。 数仓分层理论的目的是将数据仓库的功能和需求进行划分,使得数据仓库的设计更加灵活和可扩展。不同层次的数据可以根据需要进行更新和维护,同时也方便用户根据自己的需求进行数据查询和分析。数仓分层理论在数据仓库的设计和实施中起到了重要的指导作用。\[2\]\[3\] #### 引用[.reference_title] - *1* [大数据面试题--数仓](https://blog.csdn.net/weixin_42759988/article/details/123074673)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [原创|3万字剖析数仓面试题,珍藏版](https://blog.csdn.net/huzechen/article/details/123288181)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值