C++ STL中的二分法
2021/8/12 12:36:22
本文主要是介绍C++ STL中的二分法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
二分法介绍
狭义的二分法是一种在有序的数组中查找是否存在某个值的算法。广义的二分法不一定需要显式的数组,只需要有序的可能解空间即可,。
有序解空间:设[a,b]是问题P的可能解空间(解必须是整数,a,b也是整数),可能解空间有序等价于若x是问题P的合法解,则任意c小于(大于)x一定是问题的合法解。
不严谨地说,由于单调有界可知存在一个分界点,一侧是合法解,另一侧是不合法解(根据问题需要,定义分界点和某一侧重合)。
最流行的二分法是使用两个指针left和right。该方法用于查找是否存在某个值较好(狭义),但对于找分界点的问题(广义),该方法最后必然会得到left=right+1的结果,这时难以弄清楚left和right谁是真正的分界点。
查询了C++ STL代码发现,STL没有使用这种方法。在STL中,使用一个指针left,指向当前最小的未判断元素,一个count计数器,表示当前未判断元素个数。
C++ STL中的代码
Algorithm头文件中的std::lower_bound()可以在有序解空间中查找大于val的最小数下标。
std::lower_bound()代码如下:
template <class ForwardIterator, class T> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val) { ForwardIterator it; iterator_traits<ForwardIterator>::difference_type count, step; count = distance(first,last); while (count>0) { it = first; step=count/2; advance (it,step); if (*it<val) { // or: if (comp(*it,val)), for version (2) first=++it; count-=step+1; } else count=step; } return first; }
该方法需要显式的解空间作为参数,实际情况下并非所有解空间都能被显式存储,有时只知道一个函数f(),f(index)表示解空间的第index个值。在这种情况下,需要自己直接实现std::lower_bound()的功能。
代码分析
不妨设下标大于(等于)分界点的一侧为右半空间,小于(等于)分界点的一侧为左半空间。
不论左半空间和右半空间哪个是合法的,std::lower_bound()均可以找到右半空间的最小元素下标。
写代码注意点:
- while条件count>0,因为count=0表示没有数是未判断状态了,所以循环应该结束。
- if条件应该是it属于左半空间的充要条件,因为如果it满足条件直接跳到it+1,说明满足这个条件的都跳过。结合目标是找右半空间的最小元素下标可知,被跳过的都是左半空间元素。此时,由于跳过[first, first+step],共step+1个数,所以count-=step+1。
- 如果it不满足条件,那么it属于右半空间,只剩下[first,first+step-1]是未判定的元素,共count个数,所以count=step。
这篇关于C++ STL中的二分法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-29uni-app 中使用 Vant Weapp,怎么安装和配置npm ?-icode9专业技术文章分享
- 2024-12-27Nacos多环境配置学习入门
- 2024-12-27Nacos快速入门学习入门
- 2024-12-27Nacos快速入门学习入门
- 2024-12-27Nacos配置中心学习入门指南
- 2024-12-27Nacos配置中心学习入门
- 2024-12-27Nacos做项目隔离学习入门
- 2024-12-27Nacos做项目隔离学习入门
- 2024-12-27Nacos初识学习入门:轻松掌握服务发现与配置管理
- 2024-12-27Nacos初识学习入门:轻松掌握Nacos基础操作