业务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();
}
posted @ 2021-12-09 22:35  Demon90s  阅读(117)  评论(0编辑  收藏  举报