如果比较取决于返回值,尾递归是否可能?
我有一个家庭作业,要求使用直接递归来查找数组中最左边、最低的负整数的索引的函数。附加要求是函数的参数为数组和大小,并且无效值的返回值为 -999。
我想出了这个:
int LowIndexMinNeg(int src[], int size)
{
if (size == 0)
return -999;
int index = LowIndexMinNeg(src, size - 1);
if (index >= 0)
return (src[size - 1] < src[index]) ? (size - 1) : index;
else
return (src[size - 1] < 0) ? (size - 1) : index;
}
它有效,满足要求,并让我获得满分。可以用尾递归来实现吗?
在我看来,既然你必须从递归调用中获取结果来进行比较,以决定是否传递该结果或更新它,这是不可能的,但递归仍然让我的大脑陷入困境,所以我可能缺少一些明显的东西。
注意:我的家庭作业已经上交并评分。
I had a homework assignment that asked for a function that uses direct recursion to find the index of the left-most, lowest, negative integer in an array. Additional requirements were for the parameters of the function to be the array and the size and that the return value for no valid value was -999.
I came up with this:
int LowIndexMinNeg(int src[], int size)
{
if (size == 0)
return -999;
int index = LowIndexMinNeg(src, size - 1);
if (index >= 0)
return (src[size - 1] < src[index]) ? (size - 1) : index;
else
return (src[size - 1] < 0) ? (size - 1) : index;
}
It works, satisfies the requirements, and got me full credit. Can this be implemented with tail recursion?
It seems to me that since you have to take the result from the recursive call to use in a comparison to decide if you pass that one on or update it that it wouldn't be possible but recursion still ties my brain in knots a it so there might be something obvious that I'm missing.
Note: My homework assignment was already turned in and graded.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果在返回之前对递归结果进行变换,则它不是尾递归。
编辑:话虽如此,如果您想让函数尾部递归:
并调用
LowIndexMinNeg(src, src_size, src_size - 1)
编辑2:找到术语最左的最负值。您可以将其表述为第一个最负值的索引。
EDIT3:删除大部分条件,因为更容易找到最低值的索引,然后检查它是否为负数。
If you transform the result of recursion before returning, it is not tail recursive.
EDIT: Having said that, if you want to make the function tail recursive:
And call as
LowIndexMinNeg(src, src_size, src_size - 1)
EDIT2: finding the poorly termed leftmost most negative value. You can probably state that as the index of the first most negative value.
EDIT3: removing most of the conditionals, since it's easier to find the index of the lowest value, then check if it's negative.
您需要将迄今为止找到的最小数字存储在某处。通过你的函数,你正在使用堆栈
来存储它。
使用尾递归函数,您需要存储迄今为止在其他地方找到的最小数字。
例如:
您对函数的要求可能排除了所有这些,因此您留下了类似于您所拥有的代码的内容,该代码无法编写为尾递归。
要了解例如最后一点:
并且
You need to store the lowest number found so far somewhere. With your function you're using the stack
to store that.
With a tail recursive function you'll need to store the lowest number found so far elsewhere.
e.g:
The requirement you have for your function probably rules out all those, so you're left with something like the code you have, which cannot be written to be tail-recursive.
To get an idea of e.g. the 2 last point:
And
以下是使用尾递归实现该功能的方法:
此实现使用默认参数将函数全部放在一起,但这会导致界面混乱。如果您愿意,可以将其拆分为两个函数:
在本例中,
LowIndexMinNegHelper
只需是一个本地函数(我在上面用static
表示)。Here's how you might implement that using tail recursion:
This implementation uses default arguments to keep the function all together, but this makes for a messy interface. You can split this into two functions if you like:
In this case,
LowIndexMinNegHelper
only needs to be a local function (which I've indicated withstatic
above).我可能有一个提案,但当然我必须更改签名:
I might have a proposal, but of course I had to change the signature :
我不确定赋值规则是否允许定义辅助函数,但这是当操作的最自然签名不允许时实现尾递归的一种标准转换。例如:
该版本还颠倒了遍历的顺序,以便能够将“min”的“真实”值与“未找到”值区分开来。其他可能更具可读性的方法将涉及使用额外的累加器来获取实际最小值(而不仅仅是索引)和/或数组中的当前偏移量(以便可以按“正常”顺序进行遍历。但是当然,如果我编写这样的代码用于认真使用,我首先不会使用递归。
I'm not sure whether the rules for the assignment would have permitted defining an auxiliary function, but that is one standard transformation for achieving tail recursion when the most natural signature of the operation does not permit it. For example:
This version also reverses the order of traversal to make it possible to distinguish a "real" value of 'min' from the 'not found' value. Other, likely more readable, approaches would involve making use of additional accumulators for the actual minimum value (instead of only an index) and/or the current offset into the array (so that traversal can be done in "normal" order. But of course if I were coding something like this for serious use I wouldn't be using recursion in the first place.
你可以用两个静态来做到这一点......
You could do this with two statics...