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;
    }
}
posted @ 2021-12-08 00:57  Demon90s  阅读(112)  评论(0编辑  收藏  举报