【发布时间】:2020-02-17 17:18:18
【问题描述】:
所以我正在研究我用来解决代码挑战的递归方法。我相信这可能只是我的一个误解。这是递归函数。
public static boolean canSum(int[] arr, int max)
{
System.out.println(Arrays.toString(arr));
if(max == 0) return true;
if(arr.length == 0) return false;
else return canSum(Arrays.copyOfRange(arr, 1, arr.length), max) | canSum(Arrays.copyOfRange(arr, 1, arr.length), max-arr[0]);
}
现在它的工作原理是,如果我的数组中的整数在任何组合中都会给我我正在寻找的最大值,它最终会给我 true 或 false,否则它会返回 false。我不明白的是,如果我 System.out.println(Arrays.toString(arr) 我可以看到我的数组长度减少到 0,并且如果我调试它似乎到达了 if(arr.length == 0) return false; 行。那么为什么函数不会在那里中断并返回false。这个递归函数基本上一直在运行。这是我在这个用例中看到的控制台数组
System.out.println(canSum(new int[]{3,5,-1,8}, 12));
输出:
[-1, 3, 5, 8]
[3, 5, 8]
[5, 8]
[8]
[]
[]
[8]
[]
[]
[5, 8]
[8]
[]
[]
[8]
[]
[]
[3, 5, 8]
[5, 8]
[8]
[]
[]
[8]
[]
[]
[5, 8]
[8]
[]
[]
[8]
[]
[]
true
我了解 Arrays.copyOfRange 如何不断删除数组的索引,但我想我不了解运算符 | (我认为 || 也可以)以及为什么我需要max=arr[0]。根据调试,当我的 arr.length = 0 时,它看起来像 canSum(Arrays.copyOfRange(arr, 1, arr.length), max-arr[0]) 运行。那么这里的 OR 真的像递归函数调用的三元吗?我不确定 'return recurseFunct(n-1, m) | 如何返回recurseFunct (n-1, m-n[0])' 完全适用于这种情况。它看起来真的很方便,我想更好地理解它。
****** 添加此视频,因为它支持已接受的答案 *******
您可以在调试器的左侧直观地看到此递归中使用的堆栈。堆栈的大小会有所不同,直到最终完全清空。一旦为空,我将在该点的递归函数中返回 true 或 false。这对我来说是很好的学习经历。谢谢!
【问题讨论】:
-
|在设计上不是短路的。你有没有使用||的原因? -
两者都有效。我可以在此解决方案中使用任一运算符。你是对的。其实||可能会快一点,但无论哪种方式都无助于我的困惑。 :)
-
"那么为什么函数不会在那里中断并返回 false" 因为您使用的是逻辑 OR。
X || Y= X 或 Y 可能为真。所以 X 可能是假的(即你点击的断点),但仅仅因为它并不意味着 Y 不是真的,使整个表达式解析为真。 -
"我不理解位运算符
|" --- 那不是位运算符。好吧,它可以是Integer Bitwise Operator,但由于操作数是boolean值,而不是整数,所以它是Boolean Logical Operator。 -
对于位运算符术语的错误使用,我们深表歉意。为简单起见,我更新为仅在帖子中使用术语“操作员”。感谢您纠正@Andreas
标签: java algorithm recursion bitwise-operators