理解递归的问题

时间:2014-01-09 22:14:14

标签: recursion erlang

我对理解递归有疑问,我没有在书籍和教程中得到解释。以下示例在列表中找到最大值,此处我陷入第二行,我根本不理解max([H|T], Max) when H > Max ->之后发生的事情

如果我能够解释代码中的所有步骤,我会非常感激,例如为什么它会-> max(T, H);-> Max.

max([H|T]) -> max(T, H).

max([H|T], Max) when H > Max -> max(T, H);
max([_|T], Max)              -> max(T, Max);
max([],    Max)              -> Max.

非常感谢! 即

4 个答案:

答案 0 :(得分:3)

我试着一步一步解释。假设您有一个列表:[2, 3, 1]

  1. max([2, 3, 1]).

  2. H=2 , T=[3, 1]
    max([H|T]) -> max(T, H).

  3. H=3, T=[1], Max=2
    max([H|T], Max) when H > Max -> max(T, H);
    这里when块说:如果H大于Max,则再次调用max函数作为max([1],3)。

  4. 我们又来了,但有不同的价值观:
    H=1, T=[], Max=3
    max([H|T], Max) when H > Max -> max(T, H);
    1 > 3false,因此当阻止失败并尝试下一个最大功能定义时,会导致步骤5.

  5. 我们知道H小于Max因为第4步失败所以我们忽略了它 T = [], Max=3
    max([_|T], Max) -> max(T, Max);

  6. 我们匹配最后一个找到max element的函数定义:
    [] = [], Max = 3
    max([], Max) -> Max.

答案 1 :(得分:1)

理解递归的最佳方法是通过可视化来实现。让我举个简单的例子:

假设你想知道什么是成为美国总理的资格,那就是:

你必须是美国的国民,这是规则:

  1. 您是美国(或)
  2. 的天生
  3. 您的父母是美国的公民
  4. 现在,第一个选项直接让你成为美国公民,或同样的整个事情适用于你的父母,这可能会再次检查他们的父母..等等。

    所以会有一个直接的答案,这是第一选择。这称为基本案例。在第二个选项中,您可以应用同样的方法来检查您父母的公民身份。

    这是一个非常简单的伪代码,可以解释递归:

    isEligibleForPrimeMinister checkCitizenship(You, yourParents){
              Base Case {returns true(That you are US citizen)}
              checkCitizenship(yourParents, YourGrandParents)
              }
    

    希望这会有所帮助。

答案 2 :(得分:0)

这个功能可以像这样重写:

max([H|T]) -> max(T, H).

max([], Max) -> Max;
max([H|T], Max) ->
   NewMax = if H > Max -> H;
               true -> Max
            end,
   %% NewMax = erlang:max(H, Max),
   max(T, NewMax).

要理解它,你必须知道模式匹配是如何工作的。

  1. 我们采用列表的head元素并将其视为当前最大值。我们需要查看尾部的所有其余元素,并检查它们中的任何元素是否更大。
  2. 如果列表的其余部分为空,则结果为当前最大值。
  3. 如果列表不为空,请选择新的头并确定新的最大值。然后继续列表的其余部分和新的最大值。这里必须注意的是,传递给max/2的下一次迭代的列表始终是先前传递的值的尾部,因此我们不会检查已经看到的值。

答案 3 :(得分:0)

代码中的最后三行是同一函数(max/2)的不同子句。这意味着每当通过两个参数调用max函数时,它将与这三个子句进行模式匹配。

本条:

max([_|T], Max) -> max(T, Max);
只要列表非空并且列表的头部(H)小于或等于Max

就会匹配。它会调用max/2传递T这是一个列表,Max是一个数字。这个新的电话也将与三个条款进行模式匹配。

本条:

max([], Max) -> Max.
只要列表为空,

就会匹配,只返回Max这是一个数字。