• 完善排行榜的排序规则


    在之前的一篇博客中,讨论了如何合并两个排行榜。

    https://www.cnblogs.com/demon90s/p/15659594.html

    但代码上有一些瑕疵,就是排序的规则写得异常的简陋:

    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<CapabilityRankItem> 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 <vector>
    #include <string>
    #include <algorithm>
    #include <iostream>
    
    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<CapabilityRankItem> 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();
    }
    
  • 相关阅读:
    [VC++入门]C++中常用的运算符及微软自定义类型
    搜索引擎蜘蛛爬虫原理
    Enterprise Library 5.0
    Installshield 12 中文系列教程之 定义安装必要条件
    installshield脚本
    c# 事物处理
    InStallShield网络资源参考
    Could not execute query against OLE DB provider 'OraOLEDB.Oracle'
    frameset小结
    最痛心的距离
  • 原文地址:https://www.cnblogs.com/demon90s/p/15669905.html
Copyright © 2020-2023  润新知