【问题标题】:How to have a sum of numbers so that sum(4) would do 1+2+3+4如何对数字求和,以便 sum(4) 执行 1+2+3+4
【发布时间】:2019-07-29 10:50:47
【问题描述】:
-module(test).
-export([sum/1]).

sum([]) -> 0;
sum([X|Xs]) -> X + sum(Xs) 

这是我迄今为止所做的,尽管它只是将列表中的数字相加,如test:sum([1,2,3,4])

但我希望它像 test:sum(4) 一样输出 1+2...+n

我该怎么做?

【问题讨论】:

    标签: erlang erlang-shell


    【解决方案1】:

    您提供的此函数将对列表中的值求和,但如果您想“重载”此函数以也支持整数,那么您可以编写:

    -module(test).
    -export([sum/1]).
    
    sum([]) -> 0;
    sum([X|Xs]) -> X + sum(Xs);
    
    sum(0) -> 0;
    sum(N) when is_integer(N) -> (N * (N + 1)) div 2.
    

    这使用模式匹配来检查参数的类型,然后选择适当的函数“版本”进行评估。

    【讨论】:

    【解决方案2】:

    但我希望它像 test:sum(4) 一样输出 1+2...+n

    这是一个递归解决方案:

    -module(my).
    -compile(export_all).
    
    sum(0) ->
        0;
    sum(X) ->
        X + sum(X-1).
    

    在外壳中:

    3> my:sum(1).
    1
    4> my:sum(2).
    3
    5> my:sum(3).
    6
    6> my:sum(4).
    10
    7> my:sum(5).
    15
    

    请注意,如果您使用负数调用 sum/1sum/1 将永远递归并最终使 shell 崩溃,因此您可以添加一个守卫以仅接受正数。那么如果你用一个负数调用sum/1,你会得到一个function_clause错误,你会在以下情况下得到这个错误:在评估函数调用时没有找到匹配的函数子句。当然,你还可以定义另一个处理负数的函数子句。

    【讨论】:

      【解决方案3】:

      使用尾递归 这是下面的代码:

      % function entry
      sum(N) -> sum(N,0);
      
      sum(0,Acc) -> Acc;
      sum(N,Acc) -> sum(N-1,Acc+N).
      
      

      【讨论】:

        【解决方案4】:

        使用 Erlang 函数的简单一行示例:

        sum(N) -> lists:sum(lists:seq(1, N)).
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-07-04
          • 2014-12-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多