• 业务std::prev的实际应用,查询所在区间


    之前的一篇博客讨论了使用lower_bound来查询配置区间。

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

    由于配置设计的原因,从字段上面是无法看的出键所在的段的。比如:

    std::map<int, std::vector<std::string>> day_to_workings_map =
    {
    	{4, { "study", "sleep", "play" }},// 第4天之前
    	{10, { "movie", "travel", "eat" }},// 第5天到第10天
    	{20, { "interview", "go home", "watch foot ball" }}, // 第11天到第20天
    };
    

    如果 day = 5 ,那么想要知道5所在的区间的话,光读取到配置是不够的。还需要做更多的工作。这里要考虑几种情况:

    1. day小于第一个配置
    2. day大于第一个配置小于等于最大的配置
    3. day大于最大的配置

    第三种情况则无法得到所在的段。属于失败的情况。第一种则需要提供一个下限的默认值,通常是1。

    第二种情况则需要得到当前遍历迭代器的上一个迭代器位置,如何得到?可以使用 std::prev 方便的获取。

    函数如:

    bool GetDayRange(int day, int& lower, int& upper)
    {
    	auto it = day_to_workings_map.lower_bound(day);
    	if (it != day_to_workings_map.end())
    	{
    		if (it == day_to_workings_map.begin())
    		{
    			lower = 1;
    			upper = it->first;
    			return true;
    		}
    		else
    		{
    			auto pre_it = std::prev(it, 1);
    			lower = pre_it->first + 1;
    			upper = it->first;
    			return true;
    		}
    	}
    
    	return false;
    }
    

    完整测试代码如:

    std::map<int, std::vector<std::string>> day_to_workings_map =
    {
    	{4, { "study", "sleep", "play" }},// 第4天之前
    	{10, { "movie", "travel", "eat" }},// 第5天到第10天
    	{20, { "interview", "go home", "watch foot ball" }}, // 第11天到第20天
    };
    
    const std::vector<std::string>* GetWorkList(int day, int *hit_day)
    {
    	auto it = day_to_workings_map.lower_bound(day);
    	if (it != day_to_workings_map.end())
    	{
    		if (hit_day != nullptr) *hit_day = it->first;
    		return &it->second;
    	}
    	return nullptr;
    }
    
    bool GetDayRange(int day, int& lower, int& upper)
    {
    	auto it = day_to_workings_map.lower_bound(day);
    	if (it != day_to_workings_map.end())
    	{
    		if (it == day_to_workings_map.begin())
    		{
    			lower = 1;
    			upper = it->first;
    			return true;
    		}
    		else
    		{
    			auto pre_it = std::prev(it, 1);
    			lower = pre_it->first + 1;
    			upper = it->first;
    			return true;
    		}
    	}
    
    	return false;
    }
    
    int main()
    {
    	int input_day = 0;
    	std::cout << "input day: ";
    	while (std::cin >> input_day)
    	{
    		int hit_day = 0;
    		auto work_list = GetWorkList(input_day, &hit_day);
    		if (nullptr != work_list)
    		{
    			int lower = 0;
    			int upper = 0;
    			GetDayRange(input_day, lower, upper);
    
    			std::cout << "hit day: " << hit_day << "[" << lower << ", " << upper << "]" << std::endl;
    			std::cout << "work:";
    			for (const auto& work : *work_list)
    			{
    				std::cout << " " << work;
    			}
    			std::cout << "\n";
    		}
    		else
    		{
    			std::cout << "invalid day" << std::endl;
    		}
    
    		std::cout << "input day: ";
    	}
    
    	std::cin.get();
    }
    
  • 相关阅读:
    jQuery attr 与 prop 区别最简单分析
    Js事件处理模型/周期
    canvas实现点击带水纹的按钮
    js作用域问题
    js 函数里的 this
    css3: scrollLeft,scrollWidth,clientWidth,offsetWidth 的区别
    C# 中的Async 和 Await 的用法详解
    1、Task的优势
    探秘C#中的yield关键字
    详解C#中 Thread,Task,Async/Await,IAsyncResult的那些事儿
  • 原文地址:https://www.cnblogs.com/demon90s/p/15669618.html
Copyright © 2020-2023  润新知