1. 程式人生 > >水果的top k問題

水果的top k問題

題目:

本公司現在要給公司員工發波福利,在員工工作時間會提供大量的水果供員工補充營養。由於水果種類比較多,但是卻又不知道哪種水果比較受歡迎,然後公司就讓每個員工報告了自己最愛吃的k種水果,並且告知已經將所有員工喜歡吃的水果儲存於一個數組中。然後讓我們統計出所有水果出現的次數,並且求出大家最喜歡吃的前k種水果。

void AdjustDown(vector<pair<string, int>* >& rel, size_t index)
{
	size_t left = index * 2 + 1;

	while (left < rel.size())
	{
		pair<string, int> *child = rel[left];
		if (left + 1 < rel.size() && child->second > rel[left + 1]->second)
		{
			left++;
			child = rel[left];
		}
		pair<string, int> *parent = rel[index];

		if (parent->second > child->second)
		{
			rel[left] = parent;
			rel[index] = child;
			index = left;
			left = index * 2 + 1;
		}
		else
			break;
	}
}


void GetFavoriteFruit( vector<string>& fruits, size_t k)
{
	map<string, int> fru;
	vector<string>::iterator itStart = fruits.begin();  
	while (itStart != fruits.end())
	{
		const char *c = (*itStart).c_str();
		fru[c]++;
		itStart++;
	}
	//水果和其出現的次數儲存在fru中
	vector<pair<string,int>* > rel;
	/*容器呼叫resize()函式後,所有的空間都已經初始化了,所以可以直接訪問。
		而reserve()函式預分配出的空間沒有被初始化,所以不可訪問。*/
	rel.reserve(k);
	//size_t i = 0;
	map<string, int>::iterator mapIt = fru.begin();
	
	size_t i = 0;
	pair<string, int> *cur = NULL;
	for (; i < k; i++)
	{
		cur = new pair<string, int>(mapIt->first, mapIt->second);
		rel.push_back(cur);
		mapIt++;
	}
	for (int j = (k - 2) / 2; j >= 0; j--)
	{
		AdjustDown(rel, j);
	}
	while (mapIt != fru.end())
	{
		if (rel[0]->second < mapIt->second)
		{
			cur = new pair<string, int>(mapIt->first, mapIt->second);
			rel[0] = cur;
			AdjustDown(rel, 0);
		}
		mapIt++;
	}
	for (size_t i = 0; i < rel.size(); i++)
	{
		fruits[i] = rel[i]->first;
	}
	fruits.resize(k);
}


void TestFindKElem()
{
	vector<string> fr;
	fr.push_back("蘋果");
	fr.push_back("香蕉");
	fr.push_back("香蕉");
	fr.push_back("香蕉");
	fr.push_back("香蕉");
	fr.push_back("西瓜");
	fr.push_back("西瓜");
	fr.push_back("西瓜");
	fr.push_back("西瓜");
	fr.push_back("西瓜");
	fr.push_back("西瓜");
	fr.push_back("蘋果");

	fr.push_back("草莓");
	fr.push_back("草莓");
	fr.push_back("草莓");
	fr.push_back("草莓");
	fr.push_back("草莓");
	fr.push_back("草莓");
	fr.push_back("草莓");
	fr.push_back("草莓");
	fr.push_back("草莓");
	fr.push_back("草莓");

	fr.push_back("葡萄");

	fr.push_back("荔枝");
	fr.push_back("荔枝");
	fr.push_back("荔枝");

	fr.push_back("芒果");
	fr.push_back("芒果");
	fr.push_back("芒果");
	fr.push_back("芒果");
	fr.push_back("芒果");
	fr.push_back("芒果");
	fr.push_back("芒果");


	GetFavoriteFruit(fr, 4);
}