Career Cup: Map, 发帖水王

3 篇文章 0 订阅
1 篇文章 0 订阅

http://www.careercup.com/question?id=14099679

Design an algorithm that, given a list of n elements in an array, finds all the elements that appear more than n/3 times in the list. The algorithm should run in linear time ( n >=0 )
You are expected to use comparisons and achieve linear time. No hashing/excessive space/ and don't use standard linear time deterministic selection algo 

#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
typedef map<int, int> Map;
Map findOverNth(int arr[], int size, int n);
int main()
{
	//int arr[] = {5,6,7,8, 10, 10, 10,10,10,10, 4,4, 4, 4,4,1, 1,1,1}; 
	int arr[] = {5,6,7,8, 10, 4,4, 4, 4,1, 1,1};
	map<int, int>::iterator it;
	int size = sizeof(arr) / sizeof(int);
	Map map_result(findOverNth(arr, size, 3));
	for(it = map_result.begin(); it != map_result.end(); it++)
	{
		cout<<(*it).first<<endl;
	}
	return 0;
}

Map findOverNth(int arr[], int size, int n)
{
	Map a_map, result_map;
	pair<map<int, int>::iterator, bool> insert_suc;
	map<int, int>::iterator it;
	for(int i = 0; i < size; i++)
	{
		if(a_map.size() < n)
		{
			it = a_map.find(arr[i]);
			if(it != a_map.end())
			{
				(*it).second++;
			}
			else
			{
				a_map.insert(pair<int, int>(arr[i], 1));
			}
		}
		if(a_map.size() == n)
		{
			for(it = a_map.begin(); it != a_map.end();)
			{
				(*it).second--;
				if((*it).second == 0)
				{
					a_map.erase(it++);
				}
				else
					it++;
			}
		}
	}
	result_map = a_map;
	for(it = result_map.begin(); it != result_map.end(); it++)
	{
		(*it).second = 0;
	}
	for(int i = 0; i < size; i++)
	{
		it = result_map.find(arr[i]);
		if(it != result_map.end())
		{
			(*it).second++;
		}	
	}
	
	for(it = result_map.begin(); it != result_map.end();)
	{
		if((*it).second * 3 < size)
			result_map.erase(it++);
		else
			it++;
	}

	return result_map;
}
/*
#include <iostream>
#include <map>
#include <algorithm>
typedef std::map<int, int> Map;
 Map findOverNth(int arr[], int size, int n)
{
	Map ret_map; 
	typedef Map::value_type Elem; //pair<CONST int, int>
	int total = 0;
	std::for_each(arr, arr + size, [&, n](int val) 
	{
		auto ret_pair = ret_map.insert(Elem(val, 0));
		++(*ret_pair.first).second; ++ total;
		if (ret_map.size() == n)
			for (auto iter = ret_map.begin(); iter != ret_map.end(); )
			{
				--(*iter).second; -- total;
				if ((*iter).second == 0)
					ret_map.erase(iter++);
				else
					iter++;
			}
	});
	std::for_each(ret_map.begin(), ret_map.end(), [](Elem &elem) {elem.second = 0;});
	std::for_each(arr, arr + size, [&ret_map](int val) {if (ret_map.find(val) != ret_map.end()) ret_map[val] ++;});
	for (auto iter = ret_map.begin(); iter != ret_map.end(); )
	{
		if ((*iter).second <= size / n)
			ret_map.erase(iter++);
		else 
			iter++;
	}
	return ret_map;
}
using namespace std;
int main()
{
	//int arr[] = {5,6,7,8, 10, 4,4, 4, 4,1, 1,1};
	int arr[] = {5,6,7,8, 10, 10, 10,10,10,10, 4,4, 4, 4,4,1, 1,1,1};
	auto a_map = findOverNth(arr, sizeof(arr)/sizeof(int), 4);
	cout<<sizeof(arr)/sizeof(int)<<endl;
	//cout<<a_map.size()<<endl;
	for each(auto elem in a_map)
	{
		cout<<elem.first<<" "<<elem.second<<endl;
	}
}
*/


顺便讲讲map的功能。
这里红色标注的代码是一段正确的代码,但是看起来有些奇怪。
一开始的时候我是这样写的代码:
map<string,int> theMap;
// add something to theMap...

for(auto iter1 = theMap.begin(); iter1 != theMap.end(); ++iter1)
{
    if(iter1->second == xxx)
   {
        theMap.erase(iter1);  //#1 erase the element ??!!
   }
}
这样程序肯定是会有bug的,因为erase了iter1的时候,这个指针就无效了,在对它进行任何的操作都会产生问题,可能是一个无法预知的bug或者崩溃。
所以要写成:

for(auto iter1 = theMap.begin(); iter1 != theMap.end(); )
{
    if(iter1->second == xxx)
   {
        theMap.erase(iter1++);  //#1 
   }else
   {
        ++iter1;
   }
} 

好了,其他关于map的用法,查看STL的API,这里只mark一个这样的错误。后续想研究一下map背后的红黑树,当时学数据结构的时候没有学啊~


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值