我怎样才能解决这个递归
这段代码是找到一个整数数组的峰值数 问题是我得到一个错误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]
,我没有,所以它给了我这个错误。
我无法删除第一条语句的&&
并添加“或”(||
),因为那时我得到了错误的答案。请有任何想法吗?
不考虑算法的正确性,我来到了索引以下更改安全:
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;
}
它不这样工作。它只发送给我中间号码 – user2346073 2013-05-03 11:02:09
@ user2346073你应该知道你想要什么,然后再期待一些事情。你的逻辑是不正确的。 – Maroun 2013-05-03 11:02:43
我使用该递归来检查该元素的邻居是否小于特定元素。代码中的问题是它查找数组[mid + 1]的最后一个元素不存在,因为数组的大小是7,如果我查找数组[mid + 1]是8,最后一次我不想检查数组[中+ 1],因为如果最后一个元素大于预览,那么它可以返回该元素 – user2346073 2013-05-03 11:04:45
当你“的if-else-如果 - ”实现这样的decicision级联像...建设必须确保每个案件都得到处理。
此外,你必须确保任何计算数组索引对给定数组有效。这个要求可能会引入更多的“if”语句。
在你的文本中,你写了“如果我在数组的末尾或开头”,但在你的代码中没有检查这些条件的“if语句”。
我不检查该条件,因为我使用分而治之,当上次我划分我不得不只看预览元素,如果更大,那么我必须返回该元素 – user2346073 2013-05-03 11:08:53
你的代码不会做你所描述的文字。正如其他人已经说过的:目前还不清楚你想达到什么。 – mschenk74 2013-05-03 11:24:52
我想从n个元素的数组中找到峰值。 – user2346073 2013-05-03 11:27:28
就像你说的那样,问题在于当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 < 0
和mid + 1 >= myarray.length
案件处理时要特别小心。当myarray.length
仅为1
或2
时,您可能需要对案例进行一些特殊处理。
我知道我可以用这种方式解决它,但我只能使用递归。我确信它可以完成但我找不到解决方案。 – user2346073 2013-05-03 12:05:55
@ user2346073 Uhm ...您的递归涵盖一个基本情况(当峰位于数组内部时)。但是,当算法达到数组的开始或结束时,您完全忽略了递归基础案例。这些是我建议你应该在上面的提案中添加的基本案例。该算法仍然是递归的。唯一的区别是这个品种涵盖了所有必要的基础案例。 – Alderath 2013-05-03 12:48:34
你确定你了解比较是怎么回事吗? – Stefan 2013-05-03 10:51:20
你没有传递你想要搜索的元素。你想做什么? – Maroun 2013-05-03 10:54:02
我认为这会更容易,如果你指定你正在使用什么输入,当你得到的错误,例如:'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