N个数据,求最大的前K个

假设20000个数据,求取最大的前100 个,最简单的方法是对20000个数据快排,取前100 个,但这种方法有些浪费,下面有两种发现,1,快排。2,堆排序
从测试时间看,速度提升为快排的1/2,如果数据量更大,提升更多, 用Release运行

// TestOpencv.cpp : 定义控制台应用程序的入口点。
//

#include <iostream>
#include <ctime>
#include <ratio>
#include <chrono>
#include <random>
typedef struct idScore
{
	int idx;
	float score;
}IdScore;

static int compareStd(const void *a, const void * b)
{
	IdScore * aa = (IdScore *)a;
	IdScore * bb = (IdScore *)b;

	return aa->score > bb->score ? -1 : 1;

}
int main()
{

	using namespace std::chrono;
	std::vector<IdScore> mVecIdScore;
	mVecIdScore.clear();

	std::vector<IdScore> mVecIdScore1;
	mVecIdScore1.clear();


	for (int i = 0; i < 20000; i++)
	{
		IdScore mIdScore;
		mIdScore.idx = i;
		mIdScore.score = i * 1.0f * (rand() % 10000) / 1000.0f;

		mVecIdScore.push_back(mIdScore);
		mVecIdScore1.push_back(mIdScore);
	}
	// 寻找得分最大的前top_k
// 快排
	steady_clock::time_point t1 = steady_clock::now();

	std::cout << "printing out 1000 stars...\n";

	std::qsort(&mVecIdScore.data()[0], mVecIdScore.size(), sizeof(IdScore), compareStd);

	steady_clock::time_point t2 = steady_clock::now();

	duration<double> time_span = duration_cast<duration<double>>(t2 - t1);

	std::cout << "It took me " << time_span.count() << " seconds.";
	std::cout << std::endl;

// 求前100 个
	IdScore mIdScore;
	mIdScore.idx = -1;
	mIdScore.score = -FLT_MAX;
	int firstNum = 100;
	std::vector<IdScore> firstVec(firstNum, mIdScore); // 初始化前一百个
	
	t1 = steady_clock::now();

	/******************20000 个数据求最大的100 个 ************************/
	for (int i = 0; i < mVecIdScore1.size(); i++)
	{
		IdScore mIdScore = mVecIdScore1[i];
		for (int j = 0; j < 100; j++)
		{
			if (mIdScore.score >= firstVec[j].score)
			{
				firstVec.insert(firstVec.begin() + j, mIdScore);
				firstVec.erase(firstVec.begin() + 100);
				break;
			}

		}

	}
	/******************************************************************/
	t2 = steady_clock::now();
	time_span = duration_cast<duration<double>>(t2 - t1);
	std::cout << "It took me1 " << time_span.count() << " seconds.";
	std::cout << std::endl;

#if 1
	for (int i = 0; i < 100; i++)
	{
		printf("mVecIdScore ....[%d]=%f \n", i, mVecIdScore[i].score);
		printf("firstVec .......[%d]=%f \n", i, firstVec[i].score);
	}
#endif

	getchar();

    return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值