【问题标题】:Why is Collections.binarySearch giving wrong results?为什么 Collections.binarySearch 给出错误的结果?
【发布时间】:2018-07-04 05:54:58
【问题描述】:

我创建了一个列表,其中保存了一些字符串。但是,当我在此列表中进行 二分搜索 时,它会返回 负值,而该项目是 在列表中

到目前为止,当项目在列表中时,我的知识正值将返回。但是对于某些项目,它返回负数,而对于某些项目,它返回正数。

代码:

@Test
public void hello()
{
//  List<String> arlst = new ArrayList<String>();
    List arlst = new ArrayList();
    arlst.add("TP");
    arlst.add("PROVIDES");
    arlst.add("QUALITY");
    arlst.add("TUTORIALS");
    arlst.add("Stop");
    arlst.add("StopP");
    for (Iterator<String> iterator = (Iterator<String>) arlst.iterator();
            iterator.hasNext();)
    {
        Object next = iterator.next();
        System.out.println("next : " + next + " >> Search result : "
            + Collections.binarySearch(arlst, next.toString()));
    }

}

输出:

next : TP >> Search result : -7
next : PROVIDES >> Search result : -1
next : QUALITY >> Search result : 2
next : TUTORIALS >> Search result : -7
next : Stop >> Search result : 4
next : StopP >> Search result : 5

【问题讨论】:

  • 二分查找需要对 List 进行排序。
  • 请注意,您不应该使用 raw-types。写List&lt;String&gt;,而不是List。后者转换为List&lt;Object&gt;,并且在几乎每个应用程序中,您都希望将元素限制为通用类型,例如String。即使没有,那么至少写 List&lt;Object&gt; 而不是 raw-types。

标签: java collections binary-search


【解决方案1】:

原因

您收到奇怪的值,因为您的List 在调用该方法之前未排序,但这是一个要求。所以看看documentation的方法:

使用二分搜索算法在指定列表中搜索指定对象。列表必须根据其元素的自然顺序(如通过 sort(List) 方法)在进行此调用之前按升序排序。如果它未排序,则结果为未定义。如果列表包含多个等于指定对象的元素,则无法保证会找到哪一个。


说明

为了理解该要求,您需要了解二进制搜索的工作原理。这是一个小插图:

算法查看中间的元素并将其与要搜索的元素进行比较。如果给定的 needle 小于中间元素,它将继续向左搜索,否则向右搜索。现在它将查看缩小范围中间的元素并重复此过程,直到找到该元素或范围不能再分割。

如果元素没有优先排序,算法很可能会往错误的方向遍历,显然找不到元素。


解决方案

解决办法很明显,对List进行排序:

Collections.sort(arlst);

请注意,您应该不要使用原始类型。因此,写List&lt;String&gt; 而不仅仅是List。那么你的类型转换也会过时。

完整的代码可能看起来像

// Setup list
List<String> list = new ArrayList<>();
list.add("TP");
list.add("PROVIDES");
list.add("QUALITY");
list.add("TUTORIALS");
list.add("Stop");
list.add("StopP");

// Sort list
Collections.sort(list);

// Iterate all elements and use binary search
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
    String element = iter.next();
    System.out.println("element : " + element
        + " >> Search result : "
        + Collections.binarySearch(list, element));
}

【讨论】:

    【解决方案2】:

    在 API 规范中:

    使用二分搜索算法在指定列表中搜索指定对象。在进行此调用之前,列表必须根据其元素的自然顺序(如 sort(List) 方法)按升序排序。 如果未排序,则结果未定义。如果列表包含多个等于指定对象的元素,则无法保证会找到哪一个

    【讨论】:

      【解决方案3】:

      列表必须经过排序才能在其上使用 binarySearch。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-09
        • 1970-01-01
        • 2020-09-15
        相关资源
        最近更新 更多