【问题标题】:Binary Search w/o Library Methods无库方法的二分搜索
【发布时间】:2013-11-15 07:49:41
【问题描述】:

我正在尝试构建一个 binarySearch 方法,该方法通过一个 sorted 数组,并评估是否存在给定元素(以 int target 形式给出)。它将通过评估平均值是大于还是小于目标值来做到这一点,并相应地循环遍历数组的前半部分或后半部分。

我认为我已经编写了基本代码,但我遇到了一些问题:

  • int 目标 = 0; (返回真) => 正确
  • int 目标 = (3, 6, 9); (返回 false) => 应该返回 true
  • int 目标 = (15, 19, 21, 90);返回 "java.lang.ArrayIndexOutOfBoundsException: 15" => 应该为真

我想这与我在各自的 if 情况下的 for 语句有关,但我试图调试但不能。另外,我不允许使用库方法。 希望这个问题对像我这样的其他初学者有所帮助。我认为它探讨了一些 Java 概念,如语法、逻辑和基本使用。感谢您的帮助。

public class ArrayUtilities
{
public static void main(String[] args) 
{
  int[] arrayBeingSearched = {0, 3, 6, 9, 12, 15, 19, 21, 90};
  int target = 90; 
  System.out.println("linear: " + linearSearch(arrayBeingSearched, target));
  System.out.println("binary: " + binarySearch(arrayBeingSearched, target)); 

}



public static boolean binarySearch(int[] arrayBeingSearched, int target)
 {

  boolean binarySearch = false;
  for (int i = 0; i < arrayBeingSearched.length; i++){
  int left = 0; //array lower bound
  int right = arrayBeingSearched.length - 1; //array upper bound
  int middle = ((right - left) / (2)); //array mean

  if(arrayBeingSearched[middle] == target){
   binarySearch = true;
  }
  else if(arrayBeingSearched[middle] < target){

    for(int j = middle + 1; j < arrayBeingSearched.length - 1; j ++){
      int newLeft = arrayBeingSearched[j ++];
      if(arrayBeingSearched[newLeft] == target){
      binarySearch = true;
      break;
      }
      else{
        binarySearch = false;
      }

    }
  }
  else if(arrayBeingSearched[middle] > target)

    for(int l = 0; l < middle - 1; l ++){
      int newRight = arrayBeingSearched[l ++];
      if(arrayBeingSearched[newRight] == target){
      binarySearch = true;
      break;
      }
      else{
        binarySearch = false;

      }
  }

  else{
    binarySearch = false;
  }
}

return binarySearch;
}

}

好的,根据 cmets,这会是更好的表示吗?第一条评论主要回答了我的问题,但我只是想跟进:

public static boolean binarySearch(int[] array, int target)    
    {  
        int start = 0;  
        int end = array.length - 1;  

        while (start <= end)   
        {  
            int middle = start + (end - start)/2;  
            if (array[middle] == target) {  
                return true;  
            }  
            else if (array[middle] > target)    
            {  
                end = middle - 1;  
            }  
            else start = middle + 1;  
        }  
        return false;  
    }
}

【问题讨论】:

    标签: java arrays sorting binary-search indexoutofboundsexception


    【解决方案1】:

    这是一个糟糕的开始:

    for (int i = 0; i < arrayBeingSearched.length; i++)
    

    这是一个线性搜索,其中包含其他内容。我没有完全按照你在做什么,但我认为你应该重新开始......在你面前描述二分搜索。

    通常,二分搜索循环类似于:

    int left = 0;                            // Inclusive lower bound
    int right = arrayBeingSearch.length;     // Exclusive upper bound
    while (left < right) {
        // Either change left, change right, or return success
        // based on what you find
    }
    

    【讨论】:

    • @nicky478:是的,应该这样做。您使用了包含上限而不是独占上限,但这没关系。
    【解决方案2】:

    当你的中间元素小于目标时,你这样做

    int newLeft = arrayBeingSearched[j ++];
    if(arrayBeingSearched[newLeft] == target) //...
    

    如果它更大,则等价。

    也就是说,您正在获取数组的一个元素并将其用作索引。您的数组只能包含一个值为 1000 的元素,这就是您遇到 ArrayIndexOutOfBoundsException 的原因。

    【讨论】:

      【解决方案3】:

      我确定还有其他问题(请参阅 Jon 的回答),但我想提一下这样的代码:

      for(int j = middle + 1; j < arrayBeingSearched.length - 1; j ++){
        int newLeft = arrayBeingSearched[j ++];
      

      不会做你想做的事。 for 语句表示,每次程序通过循环时,它会将 1 加到 j(在循环代码的末尾)。但下一条语句将使用j 作为索引,然后将其加1。结果是每次循环时,jtwice 中都会添加 1,因此您基本上只查看其他所有元素。如果这是正确的(我认为不是),我会说您肯定需要从第二行中删除 ++

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-23
        相关资源
        最近更新 更多