2013-05-03 98 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 2013-05-03 10:51:20

+0

你没有传递你想要搜索的元素。你想做什么? – Maroun 2013-05-03 10:54:02

+1

我认为这会更容易,如果你指定你正在使用什么输入,当你得到的错误,例如:'int [] myarray = new int [] {1,2,3,4,5};'此外,它如果你确切地解释'hi'和'lo'应该是什么,那将是很好的。我认为'lo'最初是数组中第一项的索引,'hi'将是数组中最后一项的索引。但是,对于“中”的计算没有意义。例如。如果有5个项目:((lo + hi)-1)/ 2 =((0 + 4)-1)/ 2 = 3/2 = 1'但是中间项目的索引是2 – Alderath 2013-05-03 11:36:35

回答

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 2013-05-03 11:02:09

+0

@ user2346073你应该知道你想要什么,然后再期待一些事情。你的逻辑是不正确的。 – Maroun 2013-05-03 11:02:43

+0

我使用该递归来检查该元素的邻居是否小于特定元素。代码中的问题是它查找数组[mid + 1]的最后一个元素不存在,因为数组的大小是7,如果我查找数组[mid + 1]是8,最后一次我不想检查数组[中+ 1],因为如果最后一个元素大于预览,那么它可以返回该元素 – user2346073 2013-05-03 11:04:45

0

当你“的if-else-如果 - ”实现这样的decicision级联像...建设必须确保每个案件都得到处理。

此外,你必须确保任何计算数组索引对给定数组有效。这个要求可能会引入更多的“if”语句。

在你的文本中,你写了“如果我在数组的末尾或开头”,但在你的代码中没有检查这些条件的“if语句”。

+0

我不检查该条件,因为我使用分而治之,当上次我划分我不得不只看预览元素,如果更大,那么我必须返回该元素 – user2346073 2013-05-03 11:08:53

+0

你的代码不会做你所描述的文字。正如其他人已经说过的:目前还不清楚你想达到什么。 – mschenk74 2013-05-03 11:24:52

+0

我想从n个元素的数组中找到峰值。 – user2346073 2013-05-03 11:27:28

1

就像你说的那样,问题在于当mid是数组中的最后一项时,您的实现尝试查看索引mid + 1。你需要处理这种情况。像下面这样:

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 < 0mid + 1 >= myarray.length案件处理时要特别小心。当myarray.length仅为12时,您可能需要对案例进行一些特殊处理。

+0

我知道我可以用这种方式解决它,但我只能使用递归。我确信它可以完成但我找不到解决方案。 – user2346073 2013-05-03 12:05:55

+1

@ user2346073 Uhm ...您的递归涵盖一个基本情况(当峰位于数组内部时)。但是,当算法达到数组的开始或结束时,您完全忽略了递归基础案例。这些是我建议你应该在上面的提案中添加的基本案例。该算法仍然是递归的。唯一的区别是这个品种涵盖了所有必要的基础案例。 – Alderath 2013-05-03 12:48:34

相关问题