知道未必是做到!演算法的實現總讓人意外

來源:互聯網
上載者:User

問題是這樣的:
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個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.