zoukankan      html  css  js  c++  java
  • 使用C++优先队列(priority_queue)解决Top K问题

    #### 背景
    在同构的n个数据中取Top K的最大值或者最小值有很多方法,例如:
    - 排序后,取前K个或者后K个,算法复杂度为nlog(n);
    - 维护大小为K的最大(小)堆,最后取堆中的元素,算法 复杂度为nlog(k)。
    当n很大时,第二种方法可以得到显著的速度提升。本文以C++保准库提供的priotiry_queue为基础,实现基于堆的Top K算法。

    #### 步骤
    1. 创建有限队列
    ```
    //自定义结构的比较器,这里为优先级队列实现一个Great比较器,使优先级队列元素从小到大跑得了排序
    struct cmpPairSecondFloatGreat{
        bool operator() (const std::pair<int32_t, float>&a, const std::pair<int32_t, float>& b) {
            return a.second > b.second;
        }
    };
    //定义优先级队列,队列实现最小堆,即top为最小值。
    std::priority_queue<std::pair<int32_t, float>, std::vector<std::pair<int32_t, float>>, cmpPairSecondFloatGreat> noise_words;
    ```
    以取最大Top K为例,将自定义比较器给优先级队列。

    2. 更新优先级队列中的值
    ```
    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(); // 如果当前值比待插入值大,则将队头元素删除,将当前值插入队列中。
            pq.push(make_pair(1, num));
          }
        }
        vecs.push_back(make_pair(0, num));
      }
    ```

    3. 获取Top K的值
    取出有限队列中的值,即得到Top K的值。
    ```
    while (!pq.empty()) {
        cout << pq.top().second << " ";
        pq.pop();
      }
    ```
    #### 总结
    通过有限队列内部实现的堆算法,手动控制有限队列的大小,即可模拟实现基于最大(小)堆的Top K算法。

  • 相关阅读:
    BigDecimal工具类处理精度计算
    Redis的简单使用和介绍
    数据库优化知识总结
    js弹出QQ对话框在线交谈
    火焰灯menu修改之后,可以实现数遍点击小方块停留在当前页面
    js作用域的一个小例子
    js中this的四种调用模式
    jquery火焰等效果导航菜单
    appserver配置虚拟主机
    一个类似百度文库选中弹出个小框的效果
  • 原文地址:https://www.cnblogs.com/ledao/p/15085634.html
Copyright © 2011-2022 走看看