Java二进制搜索

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

正在尝试对已排序的图书对象数组执行二进制搜索

它不能很好地工作,它返回了一些对象的正确结果,但不是全部

我在纸上做了一个循环,似乎有一个数字会因为向上舍入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 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()。考虑创建一个变量,然后使用它。

  • middle=(底部+顶部)/2
    是二进制搜索实现算法中的一个典型错误。甚至编写Java集合类的Joshua Bloch也犯了这个错误(请参阅关于它的内容)。相反,请使用
    (底部+顶部)>>1
    ,以避免非常大的值出现整数溢出(您可能不会遇到此错误,但这是出于原则)

至于你的实际问题陈述,四舍五入应该是向下(整数除法),而不是向上。要解决此问题,请执行以下操作:

  • 您确定
    numberOfBooks()
    方法与您的收藏长度相对应吗
  • 您确定
    compareTo()
    方法对于您正在使用的类型能够像预期的那样工作(在您的代码示例中,我们不知道
    getReference()
    返回类型是什么)
  • 您确定您的收藏已根据
    getReference()
    正确排序吗
  • 最后,您确定使用
    givenRef.compareTo(bookCollection.get(middle.getReference())<0
    正确吗?在标准的二进制搜索实现中,它会被反转,例如
    bookCollection.get(middle).getReference().compareTo(givenRef)<0
    。这可能是donroby提到的,不确定

在任何情况下,找到错误的方法都是尝试不同的值,看看哪个输出正确,哪个不正确,从而推断出问题所在。您还可以使用调试器帮助您逐步完成算法,而不是在需要运行许多测试时使用铅笔和纸。更妙的是,正如donroby所说,编写一个单元测试。

给您一些建议:

  • 无需保留
    Book
    变量。在您的循环中,只要在找到该书时将其返回,并在最后返回
    null
    。您还可以在
    while
    条件中删除变量的布尔检查

  • middle
    变量可以在循环内确定作用域,无需延长其寿命

  • 您正在执行三次
    bookCollection.get(中间).getReference()。考虑创建一个变量,然后使用它。

  • middle=(底部+顶部)/2
    是二进制搜索实现算法中的一个典型错误。甚至编写Java集合类的Joshua Bloch也犯了这个错误(请参阅关于它的内容)。相反,请使用
    (底部+顶部)>>1
    ,以避免非常大的值出现整数溢出(您可能不会遇到此错误,但这是出于原则)

至于你的实际问题陈述,四舍五入应该是向下(整数除法),而不是向上。要解决此问题,请执行以下操作:

  • 您确定
    numberOfBooks()
    方法与您的收藏长度相对应吗
  • 您确定
    compareTo()
    方法对于您正在使用的类型能够像预期的那样工作(在您的代码示例中,我们不知道
    getReference()
    返回类型是什么)
  • 您确定您的收藏已根据
    getReference()
    正确排序吗
  • 最后,您确定使用
    givenRef.compareTo(bookCollection.get(middle.getReference())<0
    正确吗?在标准的二进制搜索实现中,它会被反转,例如
    bookCollection.get(middle).getReference().compareTo(givenRef)<0
    。这可能是donroby提到的,不确定

在任何情况下,找到错误的方法都是尝试不同的值,看看哪个输出正确,哪个不正确,从而推断出问题所在。您还可以使用调试器帮助您逐步完成算法,而不是在需要运行许多测试时使用铅笔和纸。更妙的是,正如donroby所说,编写一个单元测试。

JRL的所有建议都是正确的,但实际的失败在于您的比较是相反的

我自己并没有立即看到这一点,但将代码复制到函数中(使用字符串而不是书本),编写一些简单的Junit测试,然后在调试器中运行它们,这一点非常明显


编写单元测试

JRL的所有建议都是正确的,但实际的失败在于你的比较结果是相反的

我自己并没有立即看到这一点,但将代码复制到函数中(使用字符串而不是书本),编写一些简单的Junit测试,然后在调试器中运行它们,这一点非常明显

编写单元测试

我发现了问题

原来我在用二进制搜索我的书