2014-05-04 2 views
-3

Я реализую двоичный поиск для двух массивов. Когда я запускаю свой код, он дает мне ошибку ArrayIndexOfBoundException: 11 строка 23, где проверяется условие if (a [m] == key). Я не совсем понимаю, что это неправильно реализовано в моем коде. Пожалуйста, помогите исправить ошибкуArrayIndexOfBoundException в двоичном поиске

import java.util.Scanner; 

public class Main { 

    public static void main(String[] args) { 
     Scanner s = new Scanner(System.in); 
     int n = s.nextInt(); 
     int[] a = new int[n + 1]; 
     int i, j; 
     for (i = 0; i != a.length-1; i ++) 
      a[i] = s.nextInt(); 
     int k = s.nextInt(); 
     int[] b = new int[k+1]; 
     for (j = 0; j != b.length-1; j++) 
      b[j] = s.nextInt(); 
     int l = 0; 
     int r = a.length-1; 
     j = 0; 
     int key = b[j]; 
     int m = 0; 
     while(l <=r && j!=b.length-1){ 
      m = (l+r)/2; 
      if (a[m] == key){ 
       System.out.println(m+1); 
       j++; 
       if (j != b.length-1) 
       key = b[j]; 

      } 
      else if (a[m] > key) r = m -1; 
      else if (a[m] < key) l = m + 1; 
      if (l > r){ 
       System.out.println("-1"); 
       j++; 
       if (j != b.length-1) 
       key = b[j]; 
       l = 0; 
       r = a.length-1; 

      } 
     } 
    } 

}

+2

Вы знаете, что у вас могут быть имена переменных с несколькими буквами, верно? – kviiri

+0

Что вы понимаете по этому исключению «ArrayIndexOfBoundException»? – Braj

+1

Вам нужно решить, должна ли ваша верхняя граница быть * включительно * или * эксклюзивной *. Похоже, что это должно быть эксклюзивным, если вы начинаете с того, что это 'a.length', но условие' l <= r' предполагает, что оно включено. –

ответ

1

Массивы в Java имеют индексы, начиная с 0 и заканчивая (arrayLength - 1). Таким образом, когда вы дойдете до конца цикла while, с l == r == a.length, (l+r)/2 также равно a.length. Поскольку a.length является одним большим, чем максимальный индекс в массиве, он выходит за рамки и исключение.

+0

да, я согласен, что указывает в java, начиная с 0, но задача требует, чтобы нумерация была от 1 – user3600840

+1

. Тогда, может быть, вычесть 1 из ввода пользователя и добавить 1 перед печатью? – awksp

+0

Я меняю печать, вместо System.out.println (m) я использую System.out.println (m + 1), потому что мне нужен индекс элемента, а после компиляции я получаю правильный ответ, но тестовая система все равно напишу мне , что у меня есть «Failed test # 2. Неверный ответ « – user3600840

0

Я не знаю, почему вы используете два массива для двоичного поиска, но причиной вашего ArrayIndexOutOfBoundsException является то, что в java массивы основаны на нулевом значении, это означает, что первым элементом является элемент в позиции 0, второй в положении 1 и т. д., до последнего, который находится в положении array.length - 1. В вашем коде вы инициализируете l=1; r=a.length, и в этом проблема. Представьте себе массив с одним элементом. Он будет находиться в позиции 0 (не 1). Затем вы сделаете m=(l+r)/2 (тогда m будет 1), и вы проверите значение a[1], которое является неправильным, потому что единственным элементом в вашем массиве является a[0].

0
public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    Scanner s = new Scanner(System.in); 
    int n = s.nextInt(); 
    int[] a = new int[n + 1]; 
    int i, j; 
    for (i = 0; i < a.length; i++) 
     a[i] = s.nextInt(); 
    int k = s.nextInt(); 
    int[] b = new int[k + 1]; 
    for (j = 0; j < b.length; j++) 
     b[j] = s.nextInt(); 
    int l = 0; 
    int r = a.length - 1; 
    j = 0; 
    int key = b[j]; 
    int m = 0; 
    while (l <= r && j != b.length) { 
     m = (l + r)/2; 
     System.out.println("left " + l + " right " + r); 
     if (a[m] == key) { 
      System.out.println(m); 
      j++; 
      if (j != b.length) 
       key = b[j]; 

     } else if (a[m] > key) 
      r = m - 1; 
     else if (a[m] < key) 
      l = m + 1; 
     if (l > r) { 
      System.out.println("-1"); 
      j++; 
      if (j != b.length) 
       key = b[j]; 
      l = 1; 
      r = a.length; 

     } 
    } 
} 

как указано выше. Вы должны иметь в виду, что массивы начинаются с 0 (NOT 1), пока arrayName.length() - 1. Надеюсь это поможет.

Смежные вопросы