使用递归的最小数组值不正确
Posted
技术标签:
【中文标题】使用递归的最小数组值不正确【英文标题】:Minimum array value incorrect using recursion 【发布时间】:2017-04-14 05:30:59 【问题描述】:我正在尝试创建一种方法来使用递归搜索一维数组的最小值。它确实给了我一个输出,但无论数组是否包含“1”,它总是“1”。我对编程很陌生,感谢任何帮助。
public static int smallest(int[] array)
return smallestFrom(array, 0);
static int min = 500; //large number
private static int smallestFrom(int[] array, int i)
int x = array.length;
if (i < x && array[i] < min)
min = array[i];
i++;
smallestFrom(array, i);
else if (i < x && array[i] >= min)
i++;
smallestFrom(array, i);
return min;
输出:
2,4,6,1,6,3,8
Smallest: 1
43,76,3,23,95,23
Smallest: 1
【问题讨论】:
我刚刚跑了int array [] = 43,76,3,23,95,23; int smallest = smallestFrom(array, 0); System.out.println(smallest);
,它返回了3
对我来说也一样,代码有效
@Aaron 如果它运行一次,它就可以工作。使用第二个输入数组运行它,就像 OP 所做的那样,它会中断
【参考方案1】:
您的实现对我来说看起来不错。好吧,这有点说得太多了,但它确实有效。不过你可以改进一下:
大整数
为什么要使用一些任意数字作为“大数”?对于大于 500 的值的输入,此代码将中断。您应该只使用常量 Integer.MAX_VALUE
。没有比这个更大的值了,它以明确的方式命名,并且由 API 定义。
全局变量
这是发生错误的地方。您的实现是为一次性使用而设计的。 min
在使用第一个数组运行后将保持 1。由于第二个示例数组中没有大于 1 的数字,因此它将再次返回 1。这可以通过在每次调用 smallest
时将 min
重置为原始值来解决,或者完全放弃它(见下文)。
分支
这个问题可以用少得多的条件来解决。我们可以使用数组最大值的替代定义来代替存储最小值:
max(a, b, c, d, e, f) = max(a, max(b, c, d, e, f))
看起来更复杂?其实不是。这个想法是数组的最大值是它的第一个元素的最大值和数组中所有剩余元素的最大值。现在可以更简单地将其转换为代码。
把它们放在一起
static int min(int[] arr)
return minRec(arr, 0);
static int minRec(int[] arr, int i)
if(i == arr.length)
return Integer.MAX_VALUE;
return Math.min(arr[i], minRec(arr, i + 1));
看起来更整洁了,不是吗? Math.min(int, int)
只是一个函数的 API 实现,它返回两个参数中的最小值。
【讨论】:
那么,如果 MAX_VALUE 从未返回,我为什么需要if(i == arr.length) return Integer.MAX_VALUE;
?还有一种简单的方法可以输出索引位置吗?
@OUmSKILLS MAX_VALUE
在算法到达数组末尾时返回。但是您的数组仅包含小于Integer.MAX_VALUE
的值,因此您不会将该值作为最大值。使用空数组调用该方法,您将得到Integer.MAX_VALUE
作为结果。需要该条件来防止算法读取数组外部并抛出ArrayIndexOutOfBoundsException
。可以获得索引而不是最小值。如果两者都需要,则必须使用数组或附加类来包装函数调用的结果。
@OUmSKILLS 只需获取最小值的索引而不是实际的最小值,就可以很容易地解决索引部分的问题。您不需要两者,因为您可以简单地读取数组中返回索引处的元素,这是您的最小值。只需让minRec
返回当前最小值的索引而不是当前最小值,并相应地更新返回语句。以上是关于使用递归的最小数组值不正确的主要内容,如果未能解决你的问题,请参考以下文章