问题
2024年4月26日力扣每日一题1146.快照数组,具体题目和题解请移步力扣,遇到的问题是如下几行代码:
int get(int index, int snap_id) {
auto x = upper_bound(data[index].begin(), data[index].end(), pair{snap_id + 1, -1});
return x == data[index].begin() ? 0 : prev(x)->second;
}
这是在干什么.jpg
解释
事实证明,C++自带的二分查找方法是可以比较pair类型的数据的,参考:operator==,!=,<,<=,>,>=,<=>(std::pair) - cppreference.com,给出了7个测试用例:
- 第1、2组测试等于和不等于,规则是分别比较 lhs.first 和 rhs.first,以及 lhs.second 和 rhs.second;
- 第3—6组测试大于(等于)小于(等于),规则是按字典序比较 lhs 和 rhs,即比较首元素,然后只有在它们等价时再比较第二元素。
- 第7组是三路比较运算符,参考:synth-three-way, synth-three-way-result - cppreference.com
upper_bound和lower_bound的用法参考:关于lower_bound( )和upper_bound( )的常见用法_lowerbound和upperbound-CSDN博客,前两个参数是容器的范围,第三个参数是要比较的元素,后面缺省参数表示默认寻找第一个大于(upper_bound)或大于等于(lower_bound)的元素。比较时,按照字典序,先比较 first 元素的大小。first 满足条件时,再去比较 second 元素。由于所有 second ≥ 0,故一旦 first 匹配,second 也会匹配。此时就找到了目标 pair,返回目标位置的迭代器对象。
再说 prev,参考:C++STL常用操作之prev、next篇_c++ prev-CSDN博客,说白了就是迭代器前移一个单位。结合这道题来说,因为找到的是第一个大于 snap_id+1 的位置(这里 upper_bound 改为 lower_bound 也能通过,个人感觉大于等于更能说通),需要向前一个位置找到最后一次匹配 snap_id 的位置(因为有可能连续 set() 了很多次),输出对应位置的值就好。
菜,轻喷。错误请指出。感谢!○| ̄|_