C++左闭右开区间的理解
C++的区间是左闭右开的,关于这样做的优势,做了一个笔记整理,也处理下之前一直比较模糊的区间二分的问题。
左闭右开的区间第一个优势是,当需要取中间元素的时候,mid=begin+end/2
的定位问题。如果区间元素的个数是奇数个,那么mid
永远是指向中间的元素;如果区间元素是偶数个,那么mid
永远指向后半段区间的首元素。这样做在二分查找等一些算法的实现上特别有优势。mid
的另一个等效的写法是mid=begin+(end-begin)/2
。
比如区间的下标是0,1,2,3
,是偶数个,那么begin=0,end=4
,所以mid=(begin+end)/2=(0+4)/2=2
,正好是后半段首元素。再看区间下标是0,1,2,3,4
,是奇数个,那么begin=0,end=5
,所以mid=(begin+end)/2=(0+5)/2=2
,此时2正好是中间的元素。
在任意合理的区间[begin,end)
上,总是有mid=(begin+end)/2
把区间分成[begin,begin+mid)
和[mid,end)
两个部分。
第二个优势在于方便迭代器快速的进行终止判别。使用左闭右开的区间,迭代终止的条件是begin==end
(或者begin>=end
),这样仅需要一个条件就能终止迭代判断。
第三个优势在于快速统计区间元素的个数,n=end-begin
即为元素的个数。
上述两个优势对于特殊情况,只有一个或者两个元素的区间(这一般发生在二分之类的算法快要终止的时候),也有更好的效果。如果当前只剩下一个元素,位置是index
,则所在的区间是[index,index+1)
,因为这是奇数个元素,所以mid=(2*index+1)/2=index
,所以前半个区间是mid
元素,后半段区间是空。如果有两个元素,[index,index+1]
,那么mid=(2*index+2)/2=index+1
,正好把区间分成两个元素,又回到了仅有一个元素的情况了。
根据上述的描述,可以更好的理解二分算法了:
#include <iostream>
using std::cout;
using std::cin;
using std::endl;int BinarySearch(int Arr[], int first, int last, int val) {while(first != last) { // 终止条件int mid = first + (last - first) / 2; // 区间二分// int mid = (first + last) / 2; // 另一种等效的写法if(Arr[mid] == val) { // 找到return mid;} else if(mid > val) { // 左侧区间last = mid;} else { // 右侧区间first = mid + 1;}}return -1; // 没找到
}int main() {int A1[5] = {0, 1, 2, 3, 4};cout << "--------------测试奇数个元素----------------\n";for(int i = 0; i < 5; ++i) {cout << BinarySearch(A1, 0, 5, i) << endl;}cout << BinarySearch(A1, 0, 4, -1) << endl;cout << BinarySearch(A1, 0, 4, 5) << endl;int A2[5] = {0, 1, 2, 3};cout << "--------------测试偶数个元素----------------\n";for(int i = 0; i < 5; ++i) {cout << BinarySearch(A2, 0, 4, i) << endl;}cout << BinarySearch(A2, 0, 4, -1) << endl;cout << BinarySearch(A2, 0, 4, 4) << endl;return 0;
}
C++左闭右开区间的理解相关推荐
- 二分查找总结——左闭右开区间和左闭右闭区间(C++语言)
二分查找: 1.左闭右开区间,如有相同元素返回查找到的第一个元素. PS:主循环判断条件都是一样的(left < right),注意这里不能取等号!有相同元素时,如果要返回第一个查找到的元素,则 ...
- [201117] 为什么range范围是左闭右开区间?
[201117] 为什么range范围是左闭右开区间? range(i,j) 相当于 [i,j) 这实际上遵守的是不对称边界的设计思想,是一种编程技巧,其根本原因是为了解决程序设计中难于察觉的&quo ...
- python左闭右开区间_程序设计中左闭右开区间的广泛应用
(以下仅为个人主观看法,还请辩证看待!) 见过很多代码后不难发现,许多的程序中对于"区间"的设定,总是左闭右开[left,right).(当然,对于索引什么的是离散的数值). 甚至 ...
- 【程序设计】浅析编程语言的区间为何常是左闭右开
高中大家都学过区间--闭区间.开区间.左闭右开区间.左开右闭区间. 区间在Java里也有体现.比如用解析字符串子串的形式来提取身份证的信息,提取子串就相当于截取一个区间. 用一门语言,用的久应该会对它 ...
- 二分法闭区间开区间,二分法查找 左闭右开,划分区间
二分法查找 左闭右开,划分区间 二分法查找 左闭右开,划分区间 第一题 class Solution: def missingNumber(self, nums: List[int]) -> i ...
- leetcode704二分法:(左闭右闭+左闭右开)
前言 又重温了一遍<肖生客的救赎> 其中安迪的一句话一直回荡我的脑中:"人生可以归结为一种简单的选择:不是忙着活,就是忙着死." 多深刻,多简单,又多令人深省, 哪有那 ...
- pythonrandint函数左闭右开_Python容器类型公共方法总结
以下公共方法支持列表,元组,字典,字符串. 内置函数 Python 包含了以下内置函数: 函数 描述 备注 len(item) 计算容器中元素个数 del(item) 删除变量 del 有两种方式 m ...
- 漫画:为什么程序员喜欢使用 0 ≤ i 10 左闭右开形式写 for 循环?
作者 | 漫话编程 来源 | 漫话编程(ID:mhcoding) 当我们想要写一个循环体,期望执行10次的时候,我们会使用以下方式: for (int i=0; i<10; i++){} 可以看 ...
- 漫话:为什么程序员喜欢使用0 ≤ i 10这种左闭右开的形式写for循环?
当我们想要写一个循环体,期望执行10次的时候,我们会使用以下方式: for (int i=0; i<10; i++){} 可以看到,为了保证循环10次,我们定义了一个整数变量从0开始,然后循环1 ...
最新文章
- 力扣(LeetCode)31
- vector机器人 UPDATING YOUR VECTOR ACCOUNT 更新你的 VECTOR 帐户
- The source attachment does not contain the source for the file Activity.class
- 数组运用_1-19 编程练习
- 移动开发:android , IOS html5
- elasticsearch备份恢复(单机集群)
- 吴恩达《机器学习》学习笔记五——逻辑回归
- 想要如何入侵Linux服务器?这几个命令够用了
- Python Compiling Environment (Anaconda+VS code+GitKraken+Github)
- 信息管理软件测试工资,【用友软件工资】软件测试工程师待遇-看准网
- pygame下载(非常详细)
- php我的世界网页地图,探险家地图 - Minecraft Wiki,最详细的官方我的世界百科
- 荣耀v20屏幕测试软件,测量原来可以这么简单 荣耀V20 AR测量功能体验
- shopnc数据库操作
- 后台打log(便于查看问题和调试)方法
- PaddlePaddle深度学习7日入门CV篇Summaries
- EBMIDE——延缓显示生成,优化用户响应
- 简述Spring的详细工作原理
- c++ 贪心法构造货币统计问题
- 福建省三明市谷歌卫星地图下载