【问题标题】:returning the max of a list返回列表的最大值
【发布时间】:2011-04-15 16:22:44
【问题描述】:

我正在尝试返回列表的最大值。

我有以下代码

list_max([]) ->
    [];
list_max([H|T]) ->
    list_max(H, T).
list_max(Temp, []) ->
    Temp;
list_max(Temp, [H|T]) when H > Temp ->
    Temp = H;
list_max(Temp, T).

但我很难与 Erlang 建立联系。

如何将某些东西分配给 temp 并将其替换为最高值?

【问题讨论】:

    标签: list erlang sequential


    【解决方案1】:

    你也可以在内置函数中表达:

    -module(list_max).
    -compile(export_all).
    
    list_max([]) -> none;
    list_max([H | T] = List) ->
        lists:foldl(fun erlang:max/2, H, T);
    list_max(_) -> badarg.
    

    【讨论】:

    • 由于max 是关联的,您应该使用尾递归foldl
    • 这对我来说太多了,但谢谢。这学期刚开始在大学做erlang。
    • when is_list(List) 在这里几乎没用,因为它只检查是否存在 [] 或 [|]。它不检查“正确的列表”。
    • @Hynek 嗯...它几乎没有用...它完全没用,因为列表上的匹配(使用尖括号)已经告诉你它是一个列表。
    • 确实“when”子句完全没用,所以我也根据大众的需求进行了更正。
    【解决方案2】:

    抱歉,我可能遗漏了什么。您在寻找:

    lists:max(List). %% Find the max in List
    

    【讨论】:

    • 不,我需要自己做。 :P
    • 好! :D 谢谢。现在我可以理解文档了哈哈哈
    【解决方案3】:

    Erlang 是一个单一的赋值,所以你不能改变“变量”。您只能创建新的。

    我的建议是查看列表模块。在 lists.erl 中你会发现:

    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.
    

    您不会更新 Max 变量(在您的示例中为 Temp),而是使用新值调用函数或从函数中返回它。

    简单易懂... :-)

    【讨论】:

    • 这是正确的例子。它实际上是 Lists:max(L) 函数的 Erlang 原生实现。为什么更好?请注意,与此处发布的所有其他解决方案相比,迭代顺序提供了最佳性能。
    【解决方案4】:

    如何将某些东西分配给 temp 并将其替换为最高值?

    简短的回答是你不能。 Erlang 中的变量一旦赋值就不能更改。

    略长一点的答案是,虽然您无法在特定函数调用中更改变量,但您始终可以自递归。 Erlang 中的尾递归进行了优化。

    在您提供的示例代码中,list_max 只会查看列表的前两个元素。第四个和第五个子句都应该再次调用 list_max,第一个参数中的新值 Temp 。这是函数式语言中常见的事情。在这种情况下,Temp 被称为累加器(我经常将变量命名为 Acc 以反映这种用途,但当然您可以随意命名)。

    让我展示另一个可以被视为“介于”Macelo 的答案和 stmi 的答案之间的解决方案:

    list_max( [H|T] ) -> list_max( H , T ).
    
    list_max( X , []    ) -> X;
    list_max( X , [H|T] ) -> list_max( erlang:max(H, X) , T ).
    

    (我也放弃了检测空列表的子句,因为我认为它并没有给你带来太多好处——尽管如果你用空列表调用它,它现在会抛出异常。)

    【讨论】:

      【解决方案5】:

      Erlang 是我发现展示比解释更容易的语言之一。

      list_max([]   ) -> empty;
      list_max([H|T]) -> {ok, list_max(H, T)}.
      
      list_max(X, []   )            -> X;
      list_max(X, [H|T]) when X < H -> list_max(H, T);
      list_max(X, [_|T])            -> list_max(X, T).
      

      这样称呼它:

      {ok, Max} = list_max(MyList).
      

      【讨论】:

      • @daniel-luna 的例子是最好的。它实际上是 Lists:max(L) 函数的 Erlang 原生实现。为什么更好?请注意迭代顺序。在您的情况下,对于列表末尾的每次迭代,您都将不必要地匹配 FIRST。最佳迭代案例在 daniel-luna 示例中
      猜你喜欢
      • 2019-06-24
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      • 2023-01-30
      • 2013-02-10
      • 2017-02-07
      • 1970-01-01
      相关资源
      最近更新 更多