您的位置:首页 > 编程语言

编程之美上的寻找最大的前k个数的算法实现

2010-01-05 15:19 302 查看
   编程之美上的寻找N个数中最大的前K数,给出了一种算法,我认为比较好:
  算法是这样写的:

   假设N个数存储在数组S中,我们从数组S中随机选出一个元素X,把数组分为两部分Sa和Sb.Sa中的元素都大于X,Sb中的元素都小于X,这时,有两种可能性:
1.Sa中元素的个数小于K,Sa中所有的数和Sb中最大的K-|Sa|个数(|Sa|指Sa中元素的个数)就是数组S中最大的K个数。
2.Sa中元素的个数大于或等于K,则直接返回Sa中最大的K个元素。

平均时间复杂度O(N*log2 K)

伪代码

Kbig(S,K)
if(k<=0):
return []
if(length S<=K):
return S
(Sa,Sb)=Partition(s)
return Kbig(Sa,k).Append(Kbig(Sb,k-length Sa)
//////////////////////////////////////////////////
Partition(S):
Sa=[];
Sb=[];
Swap(s[1],S[random()%length S])
p=S[1]
for i in [2:length S]:
s[i] > p ? Sa.Append(s[i]):Sb.Append(S[i])

length Sa<length Sb ? Sa.Append(p):Sb.Append(p)
return (Sa,Sb)


我的实现

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
vector<int> Kbig(vector<int>&,int);
pair<vector<int>,vector<int> > Partition(vector<int>);
int main()
{
vector<int> origin(10000,0);
int k;
cout <<"origin array:"<<endl;
for (int i = 0;i < 10000;i++)
{
origin[i] = rand() % 10001;
cout << origin[i] << " ";
}
cout << endl;

cout << "请输入你想找的最大的数的个数:"<<endl;
cin >> k;
origin = Kbig(origin,k);

cout << "最大的" << k << "个数是:"<< endl;
for(vector<int>::iterator iter = origin.begin();iter != origin.end(); ++iter )
cout << *iter <<" ";
cout << endl;

return 0;
}

vector<int> Kbig(vector<int>& origin,int k)
{
pair<vector<int>,vector<int> > ret;
vector<int> sa,sb,temp;
if(k <= 0)
return origin;
if(origin.size() <= k)
return origin;
ret = Partition(origin);
sa = ret.first;
sb = ret.second;
if (sa.size() >= k)
{
return Kbig(sa,k);
}
else
{
temp = Kbig(sb,k - sa.size());
for (vector<int>::iterator iter = temp.begin(); iter != temp.end();++ iter)
{
sa.push_back(*iter);
}
return sa;
}

}

pair<vector<int>,vector<int> > Partition(vector<int> origin)
{
srand((unsigned)time(NULL));
vector<int> sa,sb;
pair<vector<int>,vector<int> > ret;
int p;
swap(origin[0],origin[rand()%origin.size()]);
p = origin[0];
for (vector<int>::iterator iter = origin.begin() + 1;iter != origin.end();++iter)
*iter > p ? sa.push_back(*iter) : sb.push_back(*iter);
sa.size() < sb.size() ? sa.push_back(p) : sb.push_back(p);
ret = make_pair(sa,sb);
return ret;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息