完善排行榜的排序规则
在之前的一篇博客中,讨论了如何合并两个排行榜。
但代码上有一些瑕疵,就是排序的规则写得异常的简陋:
std::sort(tmp_list.begin(), tmp_list.end(), [](const auto &lhs, const auto &rhs) { return lhs.capability > rhs.capability; });
假如遇到相同战力的,那么又该如何排序呢?通常在业务上,会有一个规则:谁先上榜,谁排前面。也就是记录一个上榜时间,谁的时间小,谁的优先级高。
那么代码可能是这样的:
struct CapabilityRankItem
{
int uid = 0;
long long capability = 0;
std::string name;
unsigned int refresh_timestamp = 0;
};
bool operator<(const CapabilityRankItem &lhs, const CapabilityRankItem& rhs)
{
// 如何定义 lhs的优先级高于rhs
if (lhs.capability != rhs.capability)
{
return lhs.capability > rhs.capability;
}
else
{
if (lhs.refresh_timestamp != rhs.refresh_timestamp)
{
return lhs.refresh_timestamp < rhs.refresh_timestamp;
}
else
{
return lhs.uid > rhs.uid;
}
}
}
注意,上述代码存在着一个不太容易发掘的问题。即判断 refresh_timestamp 时未判断与0值的判断,即0值是一个无效值,应表示未刷新过。但它又是最小,因此表示优先级高。但业务上,显然是优先级低的。
比如:
std::vector rank_list =
{
{ 2, 99, "张飞" },
{ 3, 96, "赵云" },
{ 5, 93, "黄忠" },
{ 4, 94, "马超" },
{ 10, 100, "关羽" },
{ 8, 100, "吕布", 10000 },
};
关羽和吕布对比,由于吕布刷新时间是10000,关羽是0,应当吕布排前。但实际上确是关羽排前。
解决这个问题的方法就是判断一下0:
bool operator<(const CapabilityRankItem &lhs, const CapabilityRankItem& rhs)
{
// 如何定义 lhs的优先级高于rhs
if (lhs.capability != rhs.capability)
{
return lhs.capability > rhs.capability;
}
else
{
if (lhs.refresh_timestamp != rhs.refresh_timestamp && lhs.refresh_timestamp != 0 && rhs.refresh_timestamp != 0)
{
return lhs.refresh_timestamp < rhs.refresh_timestamp;
}
else
{
return lhs.uid < rhs.uid;
}
}
}
这样就正确了。完整测试代码如下:
#include
#include
#include
#include
struct CapabilityRankItem
{
int uid = 0;
long long capability = 0;
std::string name;
unsigned int refresh_timestamp = 0;
};
bool operator<(const CapabilityRankItem &lhs, const CapabilityRankItem& rhs)
{
// 如何定义 lhs的优先级高于rhs
if (lhs.capability != rhs.capability)
{
return lhs.capability > rhs.capability;
}
else
{
if (lhs.refresh_timestamp != rhs.refresh_timestamp && lhs.refresh_timestamp != 0 && rhs.refresh_timestamp != 0)
{
return lhs.refresh_timestamp < rhs.refresh_timestamp;
}
else
{
return lhs.uid < rhs.uid;
}
}
}
std::vector rank_list =
{
{ 2, 99, "张飞" },
{ 3, 96, "赵云" },
{ 5, 93, "黄忠" },
{ 4, 94, "马超" },
{ 10, 100, "关羽" },
{ 8, 100, "吕布", 10000 },
};
int main()
{
std::sort(rank_list.begin(), rank_list.end());
for (const auto& item : rank_list)
{
std::cout << item.name << " " << item.capability << std::endl;
}
std::cin.get();
}