Java二进制搜索
正在尝试对已排序的图书对象数组执行二进制搜索 它不能很好地工作,它返回了一些对象的正确结果,但不是全部 我在纸上做了一个循环,似乎有一个数字会因为向上舍入0.5而漏掉 有没有办法让这一切顺利进行Java二进制搜索,java,binary-search,Java,Binary Search,正在尝试对已排序的图书对象数组执行二进制搜索 它不能很好地工作,它返回了一些对象的正确结果,但不是全部 我在纸上做了一个循环,似乎有一个数字会因为向上舍入0.5而漏掉 有没有办法让这一切顺利进行 Book found = null; /* * Search at the center of the collection. If the reference is less than that, * search in the upper half of the coll
Book found = null;
/*
* Search at the center of the collection. If the reference is less than that,
* search in the upper half of the collection, else, search in the lower half.
* Loop until found else return null.
*/
int top = numberOfBooks()-1;
int bottom = 0;
int middle;
while (bottom <= top && found == null){
middle = (bottom + top)/2;
if (givenRef.compareTo(bookCollection.get(middle).getReference()) == 0) {
found = bookCollection.get(middle);
} else if (givenRef.compareTo(bookCollection.get(middle).getReference()) < 0){
bottom = middle + 1;
} else if (givenRef.compareTo(bookCollection.get(middle).getReference()) > 0){
top = middle - 1;
}
}
return found;
Book found=null;
/*
*在集合的中心进行搜索。如果参考值小于该值,
*在集合的上半部分搜索,否则在下半部分搜索。
*循环直到找到,否则返回null。
*/
int top=numberOfBooks()-1;
int-bottom=0;
中间;
while(底部0){
顶部=中间-1;
}
}
发现退货;
关于Collections.binarySearch()呢?关于Collections.binarySearch()呢?给你一些建议:
- 无需保留
变量。在您的循环中,只要在找到该书时将其返回,并在最后返回Book
。您还可以在null
条件中删除变量的布尔检查while
变量可以在循环内确定作用域,无需延长其寿命middle
- 您正在执行三次
bookCollection.get(中间).getReference()。考虑创建一个变量,然后使用它。
是二进制搜索实现算法中的一个典型错误。甚至编写Java集合类的Joshua Bloch也犯了这个错误(请参阅关于它的内容)。相反,请使用middle=(底部+顶部)/2
,以避免非常大的值出现整数溢出(您可能不会遇到此错误,但这是出于原则)(底部+顶部)>>1
- 您确定
方法与您的收藏长度相对应吗numberOfBooks()
- 您确定
方法对于您正在使用的类型能够像预期的那样工作(在您的代码示例中,我们不知道compareTo()
返回类型是什么)getReference()
- 您确定您的收藏已根据
正确排序吗getReference()
- 最后,您确定使用
正确吗?在标准的二进制搜索实现中,它会被反转,例如givenRef.compareTo(bookCollection.get(middle.getReference())<0
。这可能是donroby提到的,不确定bookCollection.get(middle).getReference().compareTo(givenRef)<0
在任何情况下,找到错误的方法都是尝试不同的值,看看哪个输出正确,哪个不正确,从而推断出问题所在。您还可以使用调试器帮助您逐步完成算法,而不是在需要运行许多测试时使用铅笔和纸。更妙的是,正如donroby所说,编写一个单元测试。给您一些建议:
- 无需保留
变量。在您的循环中,只要在找到该书时将其返回,并在最后返回Book
。您还可以在null
条件中删除变量的布尔检查while
变量可以在循环内确定作用域,无需延长其寿命middle
- 您正在执行三次
bookCollection.get(中间).getReference()。考虑创建一个变量,然后使用它。
是二进制搜索实现算法中的一个典型错误。甚至编写Java集合类的Joshua Bloch也犯了这个错误(请参阅关于它的内容)。相反,请使用middle=(底部+顶部)/2
,以避免非常大的值出现整数溢出(您可能不会遇到此错误,但这是出于原则)(底部+顶部)>>1
- 您确定
方法与您的收藏长度相对应吗numberOfBooks()
- 您确定
方法对于您正在使用的类型能够像预期的那样工作(在您的代码示例中,我们不知道compareTo()
返回类型是什么)getReference()
- 您确定您的收藏已根据
正确排序吗getReference()
- 最后,您确定使用
正确吗?在标准的二进制搜索实现中,它会被反转,例如givenRef.compareTo(bookCollection.get(middle.getReference())<0
。这可能是donroby提到的,不确定bookCollection.get(middle).getReference().compareTo(givenRef)<0
在任何情况下,找到错误的方法都是尝试不同的值,看看哪个输出正确,哪个不正确,从而推断出问题所在。您还可以使用调试器帮助您逐步完成算法,而不是在需要运行许多测试时使用铅笔和纸。更妙的是,正如donroby所说,编写一个单元测试。JRL的所有建议都是正确的,但实际的失败在于您的比较是相反的 我自己并没有立即看到这一点,但将代码复制到函数中(使用字符串而不是书本),编写一些简单的Junit测试,然后在调试器中运行它们,这一点非常明显
编写单元测试 JRL的所有建议都是正确的,但实际的失败在于你的比较结果是相反的 我自己并没有立即看到这一点,但将代码复制到函数中(使用字符串而不是书本),编写一些简单的Junit测试,然后在调试器中运行它们,这一点非常明显 编写单元测试 我发现了问题 原来我在用二进制搜索我的书