使用C++優(yōu)先隊(duì)列(priority_queue)解決Top K問題

背景

在同構(gòu)的n個(gè)數(shù)據(jù)中取Top K的最大值或者最小值有很多方法,例如:

  • 排序后,取前K個(gè)或者后K個(gè),算法復(fù)雜度為nlog(n);
  • 維護(hù)大小為K的最大(?。┒眩詈笕《阎械脑?,算法 復(fù)雜度為nlog(k)。
    當(dāng)n很大時(shí),第二種方法可以得到顯著的速度提升。本文以C++保準(zhǔn)庫(kù)提供的priotiry_queue為基礎(chǔ),實(shí)現(xiàn)基于堆的Top K算法。

步驟

  1. 創(chuàng)建有限隊(duì)列
//自定義結(jié)構(gòu)的比較器,這里為優(yōu)先級(jí)隊(duì)列實(shí)現(xiàn)一個(gè)Great比較器,使優(yōu)先級(jí)隊(duì)列元素從小到大跑得了排序
struct cmpPairSecondFloatGreat{
    bool operator() (const std::pair<int32_t, float>&a, const std::pair<int32_t, float>& b) {
        return a.second > b.second;
    }
};
//定義優(yōu)先級(jí)隊(duì)列,隊(duì)列實(shí)現(xiàn)最小堆,即top為最小值。
std::priority_queue<std::pair<int32_t, float>, std::vector<std::pair<int32_t, float>>, cmpPairSecondFloatGreat> noise_words;

以取最大Top K為例,將自定義比較器給優(yōu)先級(jí)隊(duì)列。

  1. 更新優(yōu)先級(jí)隊(duì)列中的值
for (int i = 0; i < 100000000; i++) {
    float num = float(rand());
    if (pq.size() < 3){ //以Top 3為例
      pq.push(make_pair(0, num));
    } else {
      if( num < pq.top().second) {
        continue;
      } else {
        pq.pop(); // 如果當(dāng)前值比待插入值大,則將隊(duì)頭元素刪除,將當(dāng)前值插入隊(duì)列中。
        pq.push(make_pair(1, num));
      }
    }
    vecs.push_back(make_pair(0, num));
  }
  1. 獲取Top K的值
    取出有限隊(duì)列中的值,即得到Top K的值。
while (!pq.empty()) {
    cout << pq.top().second << " ";
    pq.pop();
  }

總結(jié)

通過有限隊(duì)列內(nèi)部實(shí)現(xiàn)的堆算法,手動(dòng)控制有限隊(duì)列的大小,即可模擬實(shí)現(xiàn)基于最大(?。┒训腡op K算法。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 優(yōu)先隊(duì)列的數(shù)據(jù)結(jié)構(gòu)支持兩種操作:刪除最大元素和插入元素優(yōu)先隊(duì)列的使用和隊(duì)列(刪除最老的元素)以及棧(刪除最新的元素...
    RoyTien閱讀 1,622評(píng)論 0 1
  • top-K問題指的是從一個(gè)數(shù)組中找出里面前k大或是前k小的問題。解決這類問題可以有以下的集中方法。 1、排序。排序...
    道禪_26ea閱讀 2,077評(píng)論 0 1
  • 前言 今日份的內(nèi)容很簡(jiǎn)單,看官可以放心食用。 二叉堆 這一部分完全是大學(xué)數(shù)據(jù)結(jié)構(gòu)課程的復(fù)習(xí)。 性質(zhì) 顧名思義,二叉...
    LittleMagic閱讀 2,024評(píng)論 4 12
  • 概述 因?yàn)榻⊥?,加上?duì)各種排序算法理解不深刻,過段時(shí)間面對(duì)排序就蒙了。所以決定對(duì)我們常見的這幾種排序算法進(jìn)行統(tǒng)一總...
    清風(fēng)之心閱讀 793評(píng)論 0 1
  • 夜已深,重溫一遍「阿甘正傳」,感觸太多了。我們常說(shuō):懂得很多道理,依然過不好這一生??墒窍癜⒏省⒃S三多這樣的人,都...
    1fd39acb7902閱讀 502評(píng)論 0 4

友情鏈接更多精彩內(nèi)容