2013-05-03 2 views
-2

Этот код должен найти максимальное число массива с целыми числами Проблема в том, что я получаю сообщение об ошибке Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 7.Как я могу решить эту рекурсию

public long DivideAndConquer(int lo,int hi) 
{ 
    int mid=((lo+hi)-1)/2; 
    if(myarray[mid]>=myarray[mid-1]&&myarray[mid]>= myarray[mid+1]) 
    return myarray[mid]; 
    else if (myarray[mid-1]>= myarray[mid]) 
    return DivideAndConquer(lo,mid-1); 
    else if (myarray[mid]<=myarray[mid+1]) 
    return DivideAndConquer(mid+1,hi); 
return 99; 

} 

пик число является числом, которое больше, чем их соседи, и если я в конце массива или в самом начале, то я должен смотреть только для элемента отрывков.

Я думаю, что получаю эту ошибку, потому что если мой элемент в последнем положении больше, чем предварительный просмотр, то это пик. Например, моя последняя позиция - 9, тогда у меня есть myarray[9] > myarray[8], тогда это пик, но в первом случае if он выглядит также для myarray[9+1], которого у меня нет, поэтому он дает мне эту ошибку.

Я не могу удалить && для первого оператора и добавить «или» (||), потому что тогда я получаю неправильный ответ. Любые идеи, пожалуйста?

+0

Вы уверены, что поняли, что сравнение происходит там? – Stefan

+0

Вы не передаете элемент, который хотите найти. Что ты пытаешься сделать? – Maroun

+1

Я думаю, что было бы проще, если бы вы указали, какой ввод вы используете, когда получаете ошибку, например: 'int [] myarray = new int [] {1, 2, 3, 4, 5}; было бы хорошо, если бы вы точно объяснили, что означает 'hi' и' lo'. Я думал, что 'lo' первоначально будет индексом первого элемента в массиве, а' hi' будет индексом последнего элемента в массиве. Но тогда расчет для 'mid' не имеет смысла. Например. если есть 5 элементов: '((lo + hi) -1)/2 = ((0 + 4) -1)/2 = 3/2 = 1' Но индекс среднего элемента равен 2. – Alderath

ответ

0

Не считая правильность алгоритма, я пришел к следующим изменениям для индексации безопасно:

public long DivideAndConquer(int lo,int hi) 
{ 
    int mid=(lo+hi)/2; // Valid range 
    if((lo<mid||myarray[mid]>=myarray[mid-1]) 
       &&(hi>mid||myarray[mid]>= myarray[mid+1])) 
     return myarray[mid]; 
    else if (lo<mid&&yarray[mid-1]>= myarray[mid]) 
     return DivideAndConquer(lo,mid-1); 
    else if (hi>mid&&myarray[mid]<=myarray[mid+1]) 
     return DivideAndConquer(mid+1,hi); 
    return 99; 
} 
+0

он не работает так. Он возвращает мне только среднее число – user2346073

+0

@ user2346073 Вы должны знать, чего хотите, прежде чем ожидать чего-то. Вы ошибаетесь в логике. – Maroun

+0

Я делаю эту рекурсию, чтобы проверить, меньше ли соседей этого элемента, чем определенный элемент. Проблема в коде состоит в том, что последний элемент ищет массив [mid + 1], которого нет, потому что размер массива равен 7, и если я ищу массив [mid + 1], это 8. Последний раз Я не хочу проверять массив [mid + 1], потому что если последний элемент больше, чем предварительный просмотр, тогда было бы нормально вернуть этот элемент – user2346073

0

При реализации такой decicision каскад, как в вашем «если-то еще, если -» ... строительство нужно следить за тем, чтобы каждый случай обрабатывался.

Также вы должны убедиться, что любой рассчитанный индекс массива действителен для данного массива. Это требование может ввести еще несколько «if» утверждений.

В тексте вы написали «если я нахожусь в конце массива или в начале», но в вашем коде нет «if-statements», проверяющих эти условия.

+0

. Я не проверю это условие, потому что я использую divide и conquer и последний раз, когда я делюсь, мне нужно только просмотреть элемент предварительного просмотра, и если он больше, я должен вернуть этот элемент – user2346073

+0

, ваш код не сделает то, что вы описали в тексте. Как уже говорили другие: неясно, чего вы хотите достичь. – mschenk74

+0

Я хочу найти пик из массива с n элементами. – user2346073

1

Как вы уже сказали, проблема в том, что ваша реализация пытается посмотреть на индекс mid + 1, когда mid - последний элемент в массиве. Вам нужно справиться с этим делом. Что-то вроде следующего:

public long DivideAndConquer(int lo,int hi){ 
    int mid = (lo+hi)/2; //Modified to select the middle item 
    if(mid + 1 >= myarray.length){ 
     //TODO: Handle the case when mid is the index of the last item in the array 
    } else if(mid - 1 < 0){ 
     //TODO: Handle the case when mid is the index of the first item in the array 
    } else if(myarray[mid]>=myarray[mid-1]&&myarray[mid]>= myarray[mid+1]){ 
     return myarray[mid]; 
    } else if (myarray[mid-1]>= myarray[mid]){ 
     return DivideAndConquer(lo,mid-1); 
    } else if (myarray[mid]<=myarray[mid+1]){ 
     return DivideAndConquer(mid+1,hi);' 
    } 
    return Long.MIN_VALUE; //Probably a more suitable error indicator than 99 
    //Alternatively, an exception could be thrown 
} 

Если вы используете подход, предложенный выше, быть особенно осторожными при осуществлении обработки в mid - 1 < 0 и mid + 1 >= myarray.length случаев. Возможно, вам понадобится специальная обработка случаев, когда myarray.length составляет только 1 или 2.

+0

Я знаю, что я могу решить ее также с помощью этого способа, но я могу использовать только рекурсию. я уверен, что это можно сделать, но я не нахожу решение. – user2346073

+1

@ user2346073 Uhm ... Ваша рекурсия охватывает один базовый регистр (когда пик находится внутри массива). Тем не менее, вы полностью пропустили базовый случай рекурсии, когда алгоритм достиг самого начала или конца массива. Это основные случаи, которые я предложил вам добавить в мое предложение выше. Алгоритм все еще рекурсивный. Единственное отличие состоит в том, что это разнообразие охватывает все необходимые базовые случаи. – Alderath

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