java二分查找范围区间_二分查找(Java实现)
二分查找:递归实现
public class BinarySearch {
/**
* @param arr 代查找的数组,需要有序
* @param left 查找区间的左界限
* @param right 查找区间的右界限
* @param target 待查找的值
* @param 泛型
* @return
在arr中[left...right]左闭右闭区间查找target, 找到了就返回该下角标,没找到则返回-1.
*/
public static > int search(T[] arr, int left, int right, T target) {
if (left > right) return -1;//递归结束了都没找到,返回-1.
int mid = left + (right - left) / 2; // 二分,arr[mid]作为比较的基准值。
if (arr[mid].compareTo(target) == 0) {//如果相等,说明找到
return mid;
} else if (arr[mid].compareTo(target) < 0) {//如果中间的比target小,则在右半边找
return search(arr, mid + 1, right, target);
} else {如果中间的比target大,则在左半边找
return search(arr, left, mid - 1, target);
}
}
public static > int search(T[] arr, T target) {
return search(arr, 0, arr.length - 1, target);
}
public static void main(String[] args) {
Integer[] arr = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};//二分查找需要是有序的数组
int ret = search(arr, 11);
System.out.printf("下角标是:%d\n", ret);
}
}
二分查找:非递归实现
public class BinarySearch {
public static > int search(T[] arr, T target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {//从[left ... right] 左闭右闭区间找,当left==right时,就是在判断arr[left]是否等于target
int mid = left + (right - left) / 2;
if (arr[mid].compareTo(target) < 0) {//如果中间的比target还小,那么到右半边去找
left = mid + 1;
} else if (arr[mid].compareTo(target) > 0) {//如果中间的比target大,那么到左半边去找
right = mid - 1;
} else {//如果 arr[mid] == target
return mid;
}
}
//如果没找到
return -1;
}
public static void main(String[] args) {
Integer[] arr = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};//二分查找需要是有序的数组
int ret = search(arr, 11);
System.out.printf("下角标是:%d\n", ret);
}
}
二分查找:求mid时除以2的bug问题
比如left = 1256648431, right = 1742321453 那么相加后就会上溢,得到结果 -1295997412, 除以2之后就是 -647998706,显然这个结果是不对的。
下面介绍三种方法,可以计算出正确的结果 1499484942
public class BinarySearch {
public static void main(String[] args) {
int a = 1256648431;
int b = 1742321453;
long c = (long) a + b;
System.out.printf("a + b 应该等于 %d ", c);//a + b 应该等于 2998969884 ,正确
System.out.printf("(a + b)/2 应该等于 %d\n\n", c / 2);//(a + b)/2 应该等于 1499484942 ,正确
System.out.println("整数int型用普通除法");
System.out.printf("a + b 等于 %d ", a + b);// -1295997412 ,溢出
System.out.printf("(a + b)/2 等于 %d\n\n", (a + b) / 2);// -647998706 ,溢出
System.out.println("整数int型用逻辑右移代替除法");
System.out.printf("a + b 等于 %d ", a + b);// -1295997412 ,溢出
System.out.printf("(a + b)>>>1 等于 %d\n\n", (a + b) >>> 1);// 1499484942 ,正确
System.out.println("整数int型用位运算技巧代替除法");
System.out.printf("a + b 等于 %d ", a + b);// -1295997412 ,溢出
System.out.printf("(a & b) + (a ^ b) >> 1 等于 %d\n\n", (a & b) + ((a ^ b) >> 1));// 1499484942 ,正确
}
}
给女朋友讲最后一种情况时的笔记:
目的:两个二进制数,对应位置进行相加,求出每项的项系数,也就是每位结果。
根据规律,分为两种情况。
1.对应位不同,其中一个为1,另一个为0
2.对应位相同,即同为1,或同为0
设a:1100110,b:1010101. 那么a + b = 2110211.(先不考虑进位)
处理情况1:去找规律,发现,情况为1时,相加总为1,相当于异或运算。对于情况2,异或运算总为0,不会被影响到。
处理情况2:再去找规律,发现,情况为2时,两数相加的结果要么是0,要么是2。结果总是‘&运算’结果的2倍。对于情况1,&运算结果总得到0,不会被影响到。
a:1100110
b:1010101
a^b:0110011 0 1 4 5 找到了这些项的系数
a&b:1000100 2 3 6 找到了这些项的系数
但上面这个与运算得出来的并不是真正的项系数,而是对应位置项系数的一般。所以 * 2后得
:2000200(先不考虑进位)
所以sum = (a & b) * 2 + (a ^ b)
sum / 2 = (a & b) + (a ^ b) / 2 (后续再把这个除法改成右移运算)
----------------------------------------------------------
或者换一种说法。
设a:1100110,b:1010101. 那么a + b = 2110211.(先不考虑进位)
对于a + b = 2110211.其中的2都是'&运算' 乘2得来,其中的1都是‘ ^运算 ’得来。
java二分查找范围区间_二分查找(Java实现)相关推荐
- java能写驱动吗_使用纯java jdbc驱动程序实现数据库的连接
1.准备工作: 准备相关的软件(Eclipse除外,开源软件可以从官网下载) <1>.Microsoft SQL server 2005 Express Edition <2> ...
- java文件中获取创建日期_如何在Java中获取文件的上次修改日期
java文件中获取创建日期 Sometimes we need to get the file last modified date in Java, usually for listeners li ...
- java 和c 多态比较_多态在 Java 和 C 编程语言中的实现比较
2011 年 12 月 22 日发布 众所周知,多态是面向对象编程语言的重要特性,它允许基类的指针或引用指向派生类的对象,而在具体访问时实现方法的动态绑定.C++ 和 Java 作为当前最为流行的两种 ...
- java 面试题合集_撩课-Java面试题合辑1-50题
1.简述JDK.JRE.JVM? 一.JDK JDK(Java Development Kit) 是整个JAVA的核心, 包括了Java运行环境(Java Runtime Envirnment), 一 ...
- java怎么提升编程能力_怎样提升java编程能力
1 怎样提升java编程能力 在互联网迅猛发展的时代,而我们如果对互联网一无所知,那就相当于文盲.所以很多人都想去了解它,去学习他.而作为互联网的产物--java,是一门非常不错的技术,学精通之后,你 ...
- 有谁转行学java成功了的吗_转行学习java靠谱吗?
转行学Java靠谱吗?靠不靠谱主要还是看你自己是否想要学好Java技术,是否想要从事这方面的岗位工作,如果你已经有了这个决心,那么自然而然什么都不会问题.无论我们学Java是兴趣还是想要通过学好Jav ...
- java正则截取xml节点_实例讲述Java使用正则表达式截取重复出现的XML字符串功能...
Java使用正则表达式截取重复出现的XML字符串功能示例 本文实例讲述了Java使用正则表达式截取重复出现的XML字符串功能.分享给大家供大家参考,具体如下: public static void m ...
- java 获取 反射 方法 名_乐字节Java反射之一:反射概念与获取反射源头Class
一.Java反射机制概念 "程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言",如Python, Ruby是动态语言:显然C++,Java,C#不是动态语言,但是JAV ...
- 深入java虚拟机 第四版_深入理解Java虚拟机-常用vm参数分析
Java虚拟机深入理解系列全部文章更新中... https://blog.ouyangsihai.cn/shen-ru-li-jie-java-xu-ni-ji-java-nei-cun-qu-yu- ...
最新文章
- React+Redux+中间件
- java与fabric区块链--fabric-java-jdk部署搭建--(1)
- sql if else语句_一道sql题学习if语句和case when语句
- 烽火2640路由器命令行手册-12-IBM网络配置命令
- getoutputstream java_已经为此响应调用了getOutputStream()
- 大数据可视化的重要性体现在哪里
- Elasticsearch从0.90(0.90.x)到1.2(1.x)API的变化-二
- Verilog入门教程与实例分享
- Windows Phone SDK 7.1 RTM 发布
- 第四章选择结构,根据输入的性别和身高判断是否符合招生要求,男生身高大于等于168cm,女生身高大于等于158cm。
- SQL语句的五大类:DQL、DML、DDL、DTL、DCL
- 贝壳找房的2021,依然充满变数
- 【GD32F310开发板试用】编码器接口的使用
- openCV minMaxLoc
- QCC3040/QCC3046 ANC(主动降噪)调测
- 微信小程序点击按钮弹出弹窗_微信小程序自定义弹窗(可通用)
- 恢复Excel批注框到默认位置
- RBF神经网络——基于近红外光谱的汽油辛烷值预测
- android地震监测程序,earthquake(地震监测)
- php aes加密中文,PHP AES加密 - 菜鸟要飞啊的IT小窝 - OSCHINA - 中文开源技术交流社区...
热门文章
- linux内核zfs,Linus Torvalds 不建议使用 ZFS On Linux
- Makefile:跟我一起学makefile
- apktool反编译生成java_apktool反编译工具下载|apktool反编译工具 v3.0.1 最新版-520下载站...
- android layout_margin的值,Android自定义ViewGroup( 支持layout_margin属性)
- server接收dtu透传代码_Gopher2020大会干货总结:代码技巧篇
- switch语句(JS)
- HoloLens 2开发:三种工程部署方式
- 为资产分类定义折旧范围_SAP折旧范围概念
- Windows 下的坐标系
- Spring定时任务高级使用篇