找出给定数组或文件中最小的k个数

// 30 FindMinKNum.cpp : Defines the entry point for the console application.
//
/*****************************************************************************************************
*					找出数组中最小的K个数并输出
* 《剑指offer》面试题30:输入n个整数,找出其中最小的k个数。例如:输入4,5,1,6,2,7,3,8这8个数字,则最小的
   4个数字为1,2,3,4.
*  思路1:对数组按从小到大进行排序,最前面的K个数即为最小的K个数。时间复杂度O(nlogn)。
   思路2:利用快速排序的Partition函数,找出第k小的数a,我们知道此时第k小的数的左边均小于a,右边均大于a,
   此时,直接输出数组的前k个数即可。时间复杂度O(n),可以修改输入的数组时可用。此方法的实现参见上篇
   《在O(n)时间内找到数组中任意第k小的数》
   思路3:可以先创建一个大小为k的数据容器来存储最小的k个数字,接下来每次从输入的n个整数中读入一个数。
   如果容器中已有的数字少于k个,则直接把这次读入的数据放入容器之中;
   如果容器已满,找出容器中k个数字的最大值,然后拿这次待插入的整数与其进行比较。如果插入的值比当前已有
   的最大值大,那么这个数不可能是最小的k个整数之一,于是可以抛弃这个数。如果带插入的值小于当前已有最大
   数,则删除容易中已有的最大数,并插入这个带插入的值。重复上述过程。由于每次都需要找到k个整数中最大的
   数字,很容易想到利用最大堆来实现上述过程。
******************************************************************************************************/

#include "stdafx.h"
#include 
#include 
#include 
//#include 
#include 
using namespace std;


class Compare
{
public:
	bool operator()(const int& a, const int& b)
	{
		return (a-b)>0;
	}
};

bool FindMinKNum(ifstream& ifs, const int& k, multiset& MinKNum);
bool FindMinKNum(int a[], const int& Len, const int& k, multiset& MinKNum);

int _tmain(int argc, _TCHAR* argv[])
{
	/*map students;
	pair stu1;
	pair stu2;

	stu1 = make_pair("li", 80);
	stu2 = make_pair("chen", 70);

	students.insert(stu1);
	students.insert(stu2);

	map::iterator  i;
	for(i=students.begin(); i!=students.end(); i++)
		cout<<(*i).first<<" "<<(*i).second< MinKNum;
	multiset::iterator IterBeg;
	multiset::iterator IterEnd;

	FindMinKNum(a, 8, 4, MinKNum);
	IterBeg = MinKNum.begin();
	IterEnd = MinKNum.end();
	for(; IterBeg!=IterEnd; IterBeg++)
		cout<<(*IterBeg)<<" ";
	*/
	ifstream ifs(_T("data.txt"));
	multiset MinKNum;
	multiset::iterator IterBeg;
	multiset::iterator IterEnd;

	FindMinKNum(ifs, 10, MinKNum);
	IterBeg = MinKNum.begin();
	IterEnd = MinKNum.end();
	for(; IterBeg!=IterEnd; IterBeg++)
		cout<<(*IterBeg)<<" ";
	while(true);
	return 0;
}

/**************************************************************************************
* Author:			        sky	
* Functiuon:				FindMinKNum
* Description:				找出给定文件中最小的k个数      
* Access Level:			NULL
* Input:                               ifs:输入文件流
				        k:  最小的k个数
* Output:			        MinKNum:存储找出的最小的k个数        
* Return:			        false/true       
**************************************************************************************/
bool FindMinKNum(ifstream& ifs, const int& k, multiset& MinKNum)
{
	multiset::iterator iter;
	int data;							        //	存储每次从文件读取到的数据
	int count = 0;								//	记录muliset中元素的个数
	
	ifs>>data;
	while(ifs.good())
	{
		if(k > count)
		{
			MinKNum.insert(data);
			count++;
		}
		else
		{
			iter = MinKNum.begin();
			if((*iter) > data)
			{
				MinKNum.erase(iter);
				MinKNum.insert(data);
			}
		}
		ifs>>data;
	}
	return true;
}

/**************************************************************************************
* Author:					sky	
* Functiuon:				FindMinKNum
* Description:				找出给定数组中最小的k个数      
* Access Level:			NULL
* Input:                               a:  输入数组
				        k:  最小的k个数
* Output:			        MinKNum:存储找出的最小的k个数        
* Return:			        false/true       
**************************************************************************************/
bool FindMinKNum(int* a, const int& Len, const int& k, multiset& MinKNum)
{

	if((NULL==a) || (k>Len))
		return false;

	multiset::iterator iter;
	int i = 0;			

	for(i=0; i!=Len; i++)
	{
		if(i < k)
			MinKNum.insert(a[i]);
		else
		{
			iter = MinKNum.begin();
			if((*iter) > a[i])
			{
				MinKNum.erase(iter);
				MinKNum.insert(a[i]);
			}
		}
	}
	return true;
}

输入文件:

找出给定数组或文件中最小的k个数_第1张图片

输出结果:

找出给定数组或文件中最小的k个数_第2张图片

你可能感兴趣的:(剑指offer,算法,C++,STL)