为什么Java实现的递归二分查找只能找到部分匹配项?
代码问题诊断
- 二分查找边界逻辑完全错误:二分查找的核心逻辑是根据mid值和key的大小关系缩小搜索区间,原代码中当mid对应值小于key时,错误地将区间上限
last设为mid+1,直接丢弃了右半区所有大于mid的元素,导致右半区的匹配项完全无法被检索到,这是只能统计到一半匹配结果的核心原因。 - for循环逻辑冗余且错误:每次递归进入新的mid节点时,就遍历0到mid的所有元素统计匹配,既会导致左半区元素被重复统计,也完全不会覆盖右半区大于mid的元素,完全不符合二分查找的设计逻辑,这个循环应该直接删除。
- double类型等值比较错误:采用
==直接比较double值会受浮点精度影响出现误判,正确写法是判断两个值的差值绝对值小于极小阈值,例如Math.abs(dataRecord[index-2] - key) < 1e-9。 - 等值分支无处理逻辑:当mid对应值等于key时,原代码没有任何后续处理逻辑,直接跳出分支返回结果,导致mid前后和key相等的其他匹配项全部被遗漏。
- 基本类型参数值传递问题:Java中int类型是值传递,子递归中修改的
amount变量无法同步到上层调用,最终统计值会丢失子递归中统计到的匹配数。
修复建议
如果数据量不大,直接遍历全数组统计即可,逻辑简单不易出错,示例代码如下:
public String searchMatch(int index, double key) { int amount = 0; for (int j = 0; j < count; j++) { DrillingRecord record = (DrillingRecord) data[j]; double[] dataRecord = record.getNums(); if (Math.abs(dataRecord[index-2] - key) < 1e-9) { amount++; System.out.println(record.noErrors()); } } if (amount == 0) { return "-1 \nDrilling records found: " + amount; } return "Drilling records found: " + amount; }
如果数据量很大必须用二分查找,需要先将data数组按照getNums()[index-2]的大小升序排序,再通过二分找到第一个等于key的位置,再向前后遍历所有连续相等的元素统计总数即可。
内容的提问来源于stack exchange,提问作者taryn
相关产品推荐
相关产品推荐

