【问题标题】:Why binarysearch method reduces the negative returned value by 1 [duplicate]为什么二进制搜索方法将负返回值减少1 [重复]
【发布时间】:2019-09-12 16:49:06
【问题描述】:

说说Arrays中定义的这个方法:

public static int binarySearch(int[] a, int key)

如果在数组中找不到匹配项,我无法理解为什么返回 (-(insertion point) - 1) 而不是 -(insertion point)。

https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#binarySearch(int[],%20int)

这可能是Math.abs((-(insertion point) - 1)) 等于数组大小的原因吗?

如果你想知道我为什么要问这个,我发现要找到插入点,我基本上必须做减法。

int returnedVal = Arrays.binarySearch(arr, needle);
if (returnedVal < 0) 
     insertionPoint = Math.abs(returnedVal) - 1; 

【问题讨论】:

  • 如果您认为减法过于冗长且容易出错(很容易将顺序倒退),您可以执行insertionPoint = ~returnedVal(请参阅我的回答中的编辑)

标签: java arrays binary-search


【解决方案1】:

因为 0 是合法的插入点,但您不能只返回 0,因为这意味着在索引 0 处找到了键。

编辑:请注意,选择减去 1 而不是另一个数字不是任意的。 -a - 1 等于 ~a(a 的按位否定),该函数对于所有正(和负)整数都是双射的,因为它只是翻转位并使用整个整数范围:~Integer.MIN_VALUE == Integer.MAX_VALUE,~(-1) == 0。另请注意~(~a) == a。

您可以通过~returnedVal 找到插入点。 Java 中的整数总是使用二进制补码,所以等价是有效的。

使用任何大于 1 的减数会导致 Integer.MAX_VALUE 附近的最高索引出现整数下溢。有关 ~ 运算符的更多信息,请参阅Explanation of Bitwise NOT Operator。

【讨论】:

    【解决方案2】:

    不,插入点不一定等于数组的大小;理论上,该项目可以插入到数组中的任何位置。

    可能找不到该项目,但也可能小于(已排序)数组中的所有项目。这意味着插入点是0。但是使用-(insertion point) 将意味着0 将被返回。这意味着该项目在位置0找到。他们减去一个以避免这种冲突,这样一个小于所有其他项目的项目将返回-1。

    当然,如果你真的想在数组中插入一个项目,你必须先加一个然后取反才能找到插入位置。但是考虑到您必须移动数组的内容以便为数组中的新项目腾出空间,所以做一些额外的数学运算是可以忽略不计的。

    二分查找过程完成查找插入点的工作。如果它只是返回-1,则您必须重新搜索才能找到插入点。该方法在返回“未找到”场景时为您提供了一些额外信息,如果需要将项目插入数组中,可以使用该信息。它只是需要避免0可能意味着“在第一个位置找到”和“未找到,但在开头插入”的情况。

    【讨论】:

      猜你喜欢
      • 2019-03-02
      • 2020-11-24
      • 2012-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多