知道未必是做到!算法的实现总让人意外

问题是这样的:
http://topic.csdn.net/u/20080604/16/95508149-b7a2-4f90-8797-b8423dae36fc.html
10亿个浮点数中,找出最大的10个浮点数,写出一个高性能算法。

以下是区区逛论坛时的回答:
很面熟的类型,使用stl::map来做 filter,复杂度是O(log(k) * n),这里n为10^9,为10。
程中的不变量是 amap.size() <=k ,注意编写实现就可以了。”

可是过了一会儿后,区区觉得这个回答虽然没有方向性错误,却是一个错误的回答。
所以区区花了很多时间实现自己的回答,最终的算法实现让自己很意外:
#include<iostream>
#include<iomanip>
#include<set>
using namespace std;
float genNext()
{
return rand()*1.0*rand() + rand();
}

int main()
{
multiset<float> kmax;
for(int ij=0; ij<10; ++ij)
kmax.insert(genNext());
for(int j=0; j<10; ++j)
for(int i=0; i<100000000 ;++i) {
float t = genNext();
if (*(kmax.begin()) < t) {
kmax.insert(t);
kmax.erase(kmax.begin());
}
}
multiset<float>::iterator iter=kmax.begin(),end=kmax.end();
for(; iter!=end; ++iter)
cout<<*iter<<endl;
return 0;
}

以前都把ACM算法题当饭后练习的,想到这个算法其实只不过是一眨眼的功夫。
然而在实现这个小小的想法过程是,问题一个接一个地出现,需要处理:
  • 如果使用map,会浪费多余空间,哪怕只有O(k),k=10~
  • 实现上如果输入集是可重复的话,用multiset才是正确的
  • 说有10亿个内存输入是不实际的,生成几G的测试文件更是可笑,于是用generator: genNext()
  • rand()是个耗时的操作,所以genNext()使人(区区在下)对算法的时间期望有所误判
  • 10亿真的是个烦人的数量级,用int循环得分成两部份写
  • 由于上述误判,一度花时间改用vector加std::push_heap和std::pop_heap来实现
  • 所有其它的细节…………
现在回想起来,只有 注意编写实现是正确的。
区区现在试用着KompoZer来写这个Blog,差不多是3小时后的事情了。

以后再有人问在下: “你一天能写多少行代码?”
回答是: “运气好的话,15行。”
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值