这个 ocaml 递归函数是如何工作的?

Posted

技术标签:

【中文标题】这个 ocaml 递归函数是如何工作的?【英文标题】:How does this ocaml recursive function work? 【发布时间】:2016-11-01 12:36:03 【问题描述】:

我对 ocaml 还是很陌生,我很难使用这个函数

我知道它的作用,但不知道如何!对于给定的列表,它会返回列表的最小值和列表的其余部分作为对。

sepmin [2;1;3;4] == (1,[2;3;4])

val sepmin : 'a list -> 'a * 'a list

# let rec sepmin = function
[h] -> h, []
|h::t -> let h1, t1 = sepmin t in
    min h h1, (max h h1)::t1;;

你们能帮我解决递归部分 t.t

【问题讨论】:

【参考方案1】:

首先,它递归地应用于列表的尾部。比如说,它返回h1t1,它们是尾部和尾部所有其他元素的最小值。接下来,将这个元素hh1 进行比较。如果小于h1,则返回对(h, h1::t1);否则返回一对(h1, h::t1)。由于函数是递归调用的,那么这些对中的一个可能会返回到前一个递归点(并且它的第一个元素再次与该点的列表头进行比较)。据我所知,该函数不太关心元素的原始顺序,即对于列表[1; 4; 2; 5; 6],它应该返回(1, [2; 4; 5; 6]),结果中的2和4被重新排序。

【讨论】:

我想我明白了!如果列表是 [1;2;3],则最后一次调用将是 sepmin [3],返回 3, [] 作为 h1,t1 然后是 sepmin [2,3] 和 sepmin [1;2;3] 可以是计算?如果我是对的,请告诉我,非常感谢 bipll ^^ 是的,绝对是这样。 :)【参考方案2】:

考虑递归的一个好方法是把它分成两部分。首先,当输入微不足道时,函数会做什么?其次(这是棘手的部分),假设该函数适用于小输入,它如何将较大的输入转换为较小的输入,并使用较小情况的答案来计算较大情况的正确结果。

这个函数的简单例子是一个元素的列表。在那种情况下,答案是显而易见的。

对于更长的列表,您可以使用递归能力来获得列表尾部的正确答案(这是一个较短的列表,因此递归将通过假设起作用)。一旦知道了列表尾部的答案,就可以构造完整列表的正确答案:列表头部的最大值和尾部的答案是整体最大值。您需要将这两个值中较小的一个添加回列表中。

【讨论】:

感谢您的回复杰弗里,我想我已经很好地理解了您的意思。下次我必须理解或创建函数时,我一定会考虑到这一点!

以上是关于这个 ocaml 递归函数是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

gcc -O2 对递归斐波那契函数做了啥?

使用递归创建树

这个递归是如何工作的?

如何使函数递归

下面的递归函数是如何工作的?

截断OCaml中的列表