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