C++中合併兩個排行榜的思路

最近的業務中,出現了合併排行榜的需求。兩個排行榜具體如何合併,還是要看業務的需求。

通常,一個排行榜使用一個key表示一個rank_item,對應一個分值用於排序。可能還帶有一些額外的信息,主要用於讀取。

比如,我們可以有一個戰鬥力的排名項:

struct CapabilityRankItem
{
	int uid = 0;
	long long capability = 0;
	char name[32] {};
};

我們可能用一個列表來表示它的排名:

std::vector<CapabilityRankItem> capability_rank_list;

現在的問題是,出現了兩個排行列表。如何對它進行合併?

一個做法是,先拿到排行榜A的一份拷貝TMP,我們接着遍歷排行榜B,對於B的每一項,我們會有兩個選擇:

  1. 如果該項在TMP中存在,則可能將分值相加、或取其中高者(具體看業務)
  2. 如果該項不在TMP中存在,則將該項push到TMP

完畢後,重新對TMP進行排序

最後TMP就是合併的結果。

測試代碼如下:

#include <vector>
#include <string>
#include <algorithm>
#include <iostream>

struct CapabilityRankItem
{
	int uid = 0;
	long long capability = 0;
	std::string name;
};

std::vector<CapabilityRankItem> A = 
{
    { 1, 100, "關羽"  },
    { 2, 98,  "張飛" },
    { 4, 95, "馬超" },
};

std::vector<CapabilityRankItem> B = 
{
    { 2, 99, "張飛" },
    { 3, 96, "趙雲" },
    { 5, 93, "黃忠" },
    { 4, 94, "馬超" },
};

int main()
{
    auto tmp_list = A;

    for (const auto &item : B)
    {
        auto it = std::find_if(tmp_list.begin(), tmp_list.end(), [&item](const auto &rhs) { return item.uid == rhs.uid; } );
        if (it != tmp_list.end())
        {
            if (it->capability < item.capability)
            {
                *it = item;
            }
        }
        else
        {
            tmp_list.push_back(item);
        }
    }

    std::sort(tmp_list.begin(), tmp_list.end(), [](const auto &lhs, const auto &rhs) { return lhs.capability > rhs.capability; });

    std::cout << "merge result:" << std::endl;
    for (const auto &item : tmp_list)
    {
        std::cout << item.uid << " " << item.capability << " " << item.name << std::endl;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章