简体   繁体   English

Collections.binarySearch如何工作?

[英]How does Collections.binarySearch work?

I am trying to understand how Collections.binarySearch work in Java. 我试图了解Collections.binarySearch如何在Java中工作。 I don't quite understand the output I get. 我不太了解我得到的输出。

public static void main(String args[]) {
      // create arraylist       
      ArrayList<String>  arlst=new ArrayList<String> ();


      arlst.add("A");
      arlst.add("D");
      arlst.add("C");
      arlst.add("B");
      arlst.add("E");

      int index=Collections.binarySearch(arlst, "D", Collections.reverseOrder());     

      System.out.println(index);


   }    
}

The output of this code is -1. 此代码的输出为-1。

And when the elements have been inserted at this order 并且当按此顺序插入元素时

      arlst.add("D");
      arlst.add("E");
      arlst.add("C");
      arlst.add("B");
      arlst.add("A");

I get 0 as a result. 结果我得到0。 I thought the negative number was a result if the element was not found. 如果找不到元素,我认为负数是一个结果。 Could anybody please clarify the output I receive? 有人可以澄清我收到的输出吗?

Your data must be sorted according to the given comparator for the binary search to work as intended. 您的数据必须根据给定的比较器进行排序,以便二进制搜索按预期工作。 (If it's not, the behavior is undefined.) (如果不是,则行为未定义。)

The list must be sorted into ascending order according to the specified comparator (as by the sort(List, Comparator) method), prior to making this call. 在进行此调用之前,必须根据指定的比较器(通过sort(List, Comparator)方法)将列表按升序sort(List, Comparator)

If the data is indeed sorted, the method will return the index of the sought element (if it's found) otherwise (-(insertion point) - 1) , as specified in the documentation . 如果数据确实已排序,则该方法将返回所搜索元素的索引(如果已找到),否则(-(insertion point) - 1) ,如文档中所指定。

Example: 例:

// Make sure it's sorted
Collections.sort(arlst, Collections.reverseOrder());

int index=Collections.binarySearch(arlst, "D", Collections.reverseOrder());     

System.out.println(index);  // prints 1

Just to make it clearer - why the output is -1 . 只是为了让它更清楚 - 输出为-1的原因 Yes, you didn't sort it first is a big mistake. 是的,你没先排序是一个很大的错误。 But here are some other things to take clear as well. 但这里还有其他一些事情需要明确。

As @aioobe mentioned in his answer, but he didn't make it clear enough though I think. 正如@aioobe在他的回答中所提到的那样,但我认为他并没有说清楚。 What does (-(insertion point) - 1) mean? (-(insertion point) - 1)是什么意思? Here is what the doc says. 这是文档所说的。

The index of the search key, if it is contained in the list; 搜索键的索引(如果它包含在列表中); otherwise, (-(insertion point) - 1) . 否则, ( - (插入点) - 1) The insertion point is defined as the point at which the key would be inserted into the list: the index of the first element greater than the key , or list.size() if all elements in the list are less than the specified key. 插入点定义为键将插入列表的点: 第一个元素的索引大于键 ,或者list.size(),如果列表中的所有元素都小于指定的键。 Note that this guarantees that the return value will be >= 0 if and only if the key is found. 请注意,当且仅当找到密钥时,这可以保证返回值> = 0。

So to make the answer more clear: -1 = -0 - 1 所以要使答案更清楚: -1 = -0 - 1

What I want to underline here is that the output maybe -2 or -3 or whatever. 我想在此强调的是输出可能是-2-3或其他什么。 Because if all elements in the list are less than the specified key , the output will be -list.size() - 1 . 因为如果列表中的所有元素都小于指定的键 ,则输出将为-list.size() - 1

■ Searches are performed using the binarySearch() method.
■ Successful searches return the int index of the element being searched.
■ Unsuccessful searches return an int index that represents the insertion point. The insertion point is the place in the collection/array where the element would be inserted to keep the collection/array properly sorted.
        * Return values and 0 indicate successful searches
        * Negative numbers to indicate insertion points
        * The first available insertion point is -1. Therefore,the  actual insertion point is represented as (-(insertion point) -1)

Here is the inner workings of the binarySearch method: 以下是binarySearch方法的内部工作原理:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package binarysearch;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;


public class BinarySearch {

    static ArrayList<String> strings;
    public static void main(String[] args) {
        String sample = "a quick brown fox jumped right over the lazy dog while an active lion was nowhere in sight";
        String[] simpleArray = sample.split(" ");
        strings = new ArrayList(Arrays.asList(simpleArray));
       Collections.sort(strings);
       // Enter a search string; here it is "lazy"
       binarySearch(strings, "lazy");
       System.out.println("");
       // Print the Array contents for convenience
       printArrayList(strings);
    }

    static void printArrayList(ArrayList<String> strings) {
        int i = 0;
        for (String s: strings) {
            i++;
            System.out.println(i + s );
        }
    }



    static void binarySearch (ArrayList<String> strings, String searchString) {
        boolean debug = true;
        int low = 0;
        int high = strings.size();
        int mid = 0;
        while (low <= high) {
            // The > symbol marks the hits before search is concluded
            System.out.print(">");
            mid = (high + low) / 2;

            int comparison = strings.get(mid).compareToIgnoreCase(searchString);
            if (comparison > 0) {
                high = mid - 1;
            } else if (comparison < 0) {
                low = mid + 1;
            } else {
                int temp = mid;
                System.out.println("Found '" + searchString + "' at: " + (temp + 1) );
                break;
            }
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM