【问题标题】:Erlang tail recursion for finding the number of elements in each list of the input listErlang尾递归用于查找输入列表的每个列表中的元素数
【发布时间】:2017-01-14 16:33:41
【问题描述】:

我如何在 Erlang 中使用尾递归来表示我有列表 [[1], [2], [3], [3,2]] 并且我想输出列表 [[1], [ 1], [1], [2]] 其中输出列表中的每个列表代表输入列表中每个列表的元素数?

我是函数式编程的初学者。

谢谢

【问题讨论】:

  • 显示你尝试过的代码。

标签: erlang


【解决方案1】:

我想这是一些家庭作业或自学练习,通常使用库函数或本地 erlang 结构(如列表理解)是个好主意:

List = [[1], [2], [3], [3,2]],
Result = lists:map(fun(X) -> [length(X)] end, List),
Result = [[length(X)] || X <- List],

这个问题的通常和直接的递归解决方案是

lengths_not_tail_recursive([]) -> []; % stop condition
lengths_not_tail_recursive([H|T]) -> [[length(H)]|lengths_not_tail_recursive(T)].

只要 List 不太大,这个解决方案还不错。它不是尾递归,因为在递归的每一步,除了最后一步,“本地”工作的结果都需要与后续步骤的结果相结合。

为了解决这个问题,一般的解决方法是增加一个新的参数,叫做累加器,它会在每一步记录到目前为止评估的内容,最后一步会返回最终的完整结果。

lengths_tail_recursive([],Acc) -> lists:reverse(Acc); % stop condition
% the result needs to be reverse due to the way the accumulator is built at each step
lengths_tail_recursive([H|T],Acc) -> lengths_tail_recursive(T,[[length(H)]|Acc]).

不同之处在于,在每个递归步骤中,您只需不加修改地返回下一步的结果。通常,此解决方案使用第二个函数,其作用是隐藏第二个参数的需要,并在第一次调用时正确初始化该参数

lengths(L) -> lengths_tail_recursive(L,[]).

注意:尾递归解决方案使用 2 个库函数:length/1 和 lists:reverse/1。我邀请您以尾递归的方式编写它们

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 2011-09-22
    • 2016-03-10
    • 2018-06-13
    • 2013-03-17
    • 1970-01-01
    相关资源
    最近更新 更多