最近的业务中,出现了合并排行榜的需求。两个排行榜具体如何合并,还是要看业务的需求。
通常,一个排行榜使用一个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的每一项,我们会有两个选择:
- 如果该项在TMP中存在,则可能将分值相加、或取其中高者(具体看业务)
- 如果该项不在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;
}
}