用 C++ 设计排行榜

c++server side programmingprogramming

假设我们要设计一个排行榜类,有三个不同的函数 −

  • addScore(playerId, score) − 这将通过将分数添加到给定玩家的分数来更新排行榜。当排行榜中没有具有给定 id 的玩家时,将他添加到具有给定分数的排行榜中。
  • top(K) − 这将返回前 K 名玩家的分数总和。
  • reset(playerId) −这会将具有给定 id 的玩家的分数重置为 0。保证在调用此函数之前玩家已被添加到排行榜。

最初,排行榜应该是空的。

如果我们执行如下操作 −

  • Leaderboard leaderboard = new Leaderboard ();
  • leaderboard.addScore(1,73); // 排行榜为 [[1,73]];
  • leaderboard.addScore(2,56); // 排行榜为 [[1,73],[2,56]];
  • leaderboard.addScore(3,39); // 排行榜为 [[1,73],[2,56],[3,39]];
  • leaderboard.addScore(4,51); // 排行榜为 [[1,73],[2,56],[3,39],[4,51]];
  • leaderboard.addScore(5,4); // 排行榜为 [[1,73],[2,56],[3,39],[4,51],[5,4]];
  • leaderboard.top(1); // 返回 73;
  • leaderboard.reset(1); // 排行榜为 [[2,56],[3,39],[4,51],[5,4]];
  • leaderboard.reset(2); // 排行榜为 [[3,39],[4,51],[5,4]];
  • leaderboard.addScore(2,51); // 排行榜为 [[2,51],[3,39],[4,51],[5,4]];
  • leaderboard.top(3); // 返回 141 = 51 + 51 + 39;

为了解决这个问题,我们将遵循以下步骤 −

  • 定义一个名为 pq 的整数对优先级队列,创建一个 int 类型键和 int 类型值 m 的映射。对于初始化,它将清除映射,如果队列不为空,则从队列中删除所有元素。
  • addScore() 方法将类似于 −
    • 如果存在 playerId,则 m[playerId] := m[playerId] + score
    • 将一对 (m[playerId], playerId) 插入 pq
    • 否则 m[playerId] = score
  • top() 方法将类似于
  • 创建一个对 temp 的向量,设置 sum := 0
  • 当 k 不为 0
    • curr := pq 的顶部,从 pq 中删除
    • 如果 m[curr 对的第二个值] = curr 对的第一个值
      • 将 k 减少1
      • sum := sum + curr 的第一个值
      • 将 curr 插入到 temp 中
  • 对于 i,范围从 0 到 temp 的大小
    • 将 temp[i] 插入 pq
  • reset() 函数将类似于 −
    • m[playerId] = 0

示例(C++)

让我们看下面的实现,以便更好地理解 −

#include <bits/stdc++.h>
using namespace std;
class Leaderboard {
public:
   priority_queue< pair <int,int> > pq;
   map < int, int > m;
   Leaderboard() {
      m.clear();
      while(!pq.empty())pq.pop();
   }
   void addScore(int playerId, int score) {
      if(m.find(playerId)!=m.end()){
         m[playerId] += score;
      }
      else m[playerId] = score;;
         pq.push({m[playerId], playerId});
   }
   int top(int k) {
      vector < pair <int,int> > temp;
      int sum = 0;
      while(k){
         pair <int, int> curr = pq.top();
         pq.pop();
         if(m[curr.second] == curr.first){
            k--;
            sum += curr.first;
            temp.push_back(curr);
         }
      }
      for(int i = 0; i < temp.size(); i++)pq.push(temp[i]);
      return sum;
   }
   void reset(int playerId) {
      m[playerId] = 0;
   }
};
main(){
   Leaderboard ob;
   ob.addScore(1,73);
   ob.addScore(2,56);
   ob.addScore(3,39);
   ob.addScore(4,51);
   ob.addScore(5,4);
   cout <<ob.top(1) << endl;
   ob.reset(1);
   ob.reset(2);
   ob.addScore(2,51);
   cout <<ob.top(2) << endl;
}

输入

Initialize leader board then use the functions to see different results. See the main() function

输出

73
102

相关文章