在Java中将getMax重写为递归方法
我正在做这个作业,我在递归地编写这个方法时遇到了困难。 我有这样一种方法,它是有效的,但不是递归的:在Java中将getMax重写为递归方法,java,arrays,recursion,max,Java,Arrays,Recursion,Max,我正在做这个作业,我在递归地编写这个方法时遇到了困难。 我有这样一种方法,它是有效的,但不是递归的: public static <T extends Comparable< ? super T>> T getLargest(T [] a, int low, int high) { if(low>high) throw new IllegalArgumentException(); return
public static <T extends Comparable< ? super T>> T getLargest(T [] a, int low,
int high)
{
if(low>high)
throw new IllegalArgumentException();
return Collections.max(Arrays.asList(Arrays.copyOfRange(a, low, high)));
public static>T getmax(T[]a,int-low,
整数(高)
{
如果(低>高)
抛出新的IllegalArgumentException();
返回Collections.max(Arrays.asList(Arrays.copyOfRange(a,低,高));
因此,我从这里开始讨论这个问题,它是一种扩展,但也不是递归的:
T[] arrCopy = (T[]) new Object[high-low];
for(int i=low;i<high;i++){
if(a[i].compareTo(a[i-1])>0)
arrCopy[i]=a[i];
else
arrCopy[i]=a[i+1];
}
return arrCopy[0];
T[]arrCopy=(T[])新对象[high-low];
对于(int i=低;i0)
arrCopy[i]=a[i];
其他的
arrCopy[i]=a[i+1];
}
返回副本[0];
我已经花了好几个小时来研究它,但似乎没有办法让它递归并工作。
非常感谢任何帮助和想法 下面是一个模板,用于将for循环转换为尾部递归方法:
//iterative version
public Object getIteratively(Object[] a) {
Object retVal = null;
for (int i = 0; i < a.length; a++ ) {
//do something
}
return retVal;
}
//recursive version
public Object getRecursively(Object[] a) {
doGetRecursively(a, 0, null);
}
private Object doGetRecursively(Object[] a, int i, Object retVal) {
if ( i == a.length ) {
return retVal;
}
//do something
return doGetRecursively(a, i+1, retVal);
}
首先,您的方法签名不正确。你不需要一个“低”。您应该将数组/列表作为输入,并返回最大的元素。但是,您可能会发现需要一个需要额外参数的辅助方法 当接近递归时,如果您陷入困境,通常最好先确定基本情况,然后再处理递归情况 你的基本情况是你知道答案的最简单的情况。在这个问题中,如果列表的大小为1,您马上就知道最大的元素是什么——您只需返回唯一的元素。您可能还需要考虑列表为空的情况
因此,递归情况是当列表的大小大于1时。在递归情况下,您希望尝试“断开一部分”,然后将其余部分发送给递归调用。在这种情况下,您可以查看列表中的第一个元素,并将其与对列表其余部分的递归调用得到的结果进行比较。这将是正确的答案:
T tmp = a[low];
for(int i=0;i<=high;i++){
if(a[i].compareTo(tmp)>0){
tmp = a[i];
getLargest(a,i,high);
}
}
return tmp;
T tmp=a[low];
对于(int i=0;i0){
tmp=a[i];
最大值(a、i、高);
}
}
返回tmp;
好的,在这个问题失控之前,这里有一个简单的迭代和等效的递归解决方案,它是用int实现的,所以您必须对它做一点修改;)
public static int getmax(int[]vals){
int max=vals[0];
对于(int i=1;i
注意,对于递归问题,通常下界是包含的,而上界是独占的。我们也可以以不同的方式实现它,但是通常的分治方法非常有用,并且非常适合于使用fork框架进行并行化,所以这很好。(对于空数组,两个版本都会失败)这是一个非常糟糕的递归候选者。你不会比O(n)comparison做得更好,所以你不会分裂和征服;你使用递归是完全没有理由的。还要不惜一切代价避免使用泛型数组。他们要求头痛。接受
列表
而不是T[]
。另外,请先修复您的迭代版本-看在上帝的份上,为什么您要为GetMax分配一个数组?!如果你有一个合理的迭代版本,那么应该清楚地知道如何继续。@Mark:谢谢你的回复,我知道这不是递归的最佳示例。我只是为了考试准备学习一些例子。这并不是为了得到比O(n)更好的时机。但要从课堂上给出的例子中练习递归。如果时间和有效性是一个问题,我会使用我的第一个代码。@Voo好的想法是检查第一个元素,并将其与下一个元素进行比较,然后再次调用该方法检查下一个元素,依此类推。从我把它写在纸上开始整理,它可以用几行来完成,但由于某些原因,我无法使它正常工作。
T tmp = a[low];
for(int i=0;i<=high;i++){
if(a[i].compareTo(tmp)>0){
tmp = a[i];
getLargest(a,i,high);
}
}
return tmp;
public static int getLargest(int[] vals) {
int max = vals[0];
for (int i = 1; i < vals.length; i++) {
max = Math.max(max, vals[i]);
}
return max;
}
public static int getLargestRec(int[] vals) {
return getLargestRec(vals, 0, vals.length);
}
private static int getLargestRec(int[] vals, int low, int high) {
if (low + 1 == high) {
return vals[low];
}
int middle = low + (high - low) / 2;
int left = getLargestRec(vals, low, middle);
int right = getLargestRec(vals, middle, high);
return Math.max(left, right);
}
public static void main(String[] args) {
int[] vals = {5, 23, 32, -5, 4, 6};
System.out.println(getLargestRec(vals));
System.out.println(getLargest(vals));
}