【问题标题】:ERLANG, infinite Fibonacci list using zipWithERLANG,使用 zipWith 的无限斐波那契列表
【发布时间】:2015-06-28 06:37:10
【问题描述】:

我有一个包含无限列表的任务。

我必须为无限列表编写一个 zipWith/3 - 完成

我必须使用这个 zipWith/3 来创建一个无限的带有 fib/0 的斐波那契数列 - 问题

我必须写 fibs(N) 从 fib() 中取出前 N 个元素 - 完成

这是我目前所拥有的:

-module(zipWith).
-export([take/2, zipWith/3, fib/0]).

take(0, _)         -> [];
take(N, [H|LazyT]) -> [H | take(N-1, LazyT())].

zipWith(F, [H1|L1], [H2|L2]) -> [F(H1, H2) | fun() -> zipWith(F, L1(),   L2()) end].

fib() -> ...
fib(L) -> zipWith(fun(X,Y) -> X + Y end, L(), tl(L())).

fibs(N) -> take(N, fib()).

我知道 fib/1 应该是这样的(我很确定 - 纠正我,如果我弄错了)。获取列表本身和没有头部的列表。因此,如果 [0,1,...] zipWith(add,[0,1,...],[1,...]) 导致最后两个数字相加。但是无论我尝试作为这个 fib()->... 的开头,都会导致错误。 我想以某种方式表达它: fib() -> fib([[0,1] ++ fun() -> ... end]...)

我不知何故想用 [0,1,fun()...] 开始 fib/1,但不知道如何让列表开始。

提前感谢您的建议

【问题讨论】:

    标签: list erlang fibonacci infinite


    【解决方案1】:

    我不明白你打算如何在这里使用zipwith。但是,我想出了以下解决方案:

    map(_, []) -> [];
    map(F, [H | T]) -> [F(H) | fun() -> map(F, T()) end].
    
    fib1(X, Y) -> [{X, Y} | fun() -> fib1(Y, X+Y) end].
    
    fib() -> map(fun({_X, Y}) -> Y end, fib1(1,1)).
    

    这个想法是构建一些元素,然后将上下文传递给下一个数字。

    实际上我不认为这种方法实现了真正的懒惰,因为每次遍历列表时都必须重新评估所有值。

    更新

    如果您想通过zipWith 来实现这一点,您可以绕过这样一个事实,即序列的每个下一个元素都是由前一个元素和当前元素之和形成的。

    因此,您可以获取一个元素列表,以及一个移动了一个元素的列表,并将每个下一个元素形成为这些列表中元素的总和。

    您将需要一些第一个元素来引导。您只需应用前两个元素的知识

    如你所见,在计算第 3 个元素时你必须先知道 2,在计算第 4 个元素时,你必须知道第 2 和第 3,但你已经计算了第 3。

    %% this eveluates the lazy list and just returns normal one
    e(L) when is_list(L) -> L; 
    e(LazyL) when is_function(LazyL, 0) -> LazyL().
    
    take(0, _)         -> [];
    take(N, [H|LazyT]) -> [H | take(N-1, e(LazyT))].
    
    drop(0, T)         -> e(T);
    drop(N, [_|LazyT]) -> drop(N-1, e(LazyT)).
    
    zipWith(F, [H1|L1], [H2|L2]) -> [F(H1, H2) | fun() -> zipWith(F, e(L1),   e(L2)) end].
    
    fib() -> [1, 1 | fun() -> zipWith(fun(X,Y) -> X + Y end, fib(), drop(1, fib())) end ].
    
    fibs(N) -> take(N, fib()).
    

    最后的笔记

    1. 在现实生活中千万不要这样写。
    2. 这类更有趣的任务是实施埃拉托色尼筛。后一个任务不是那么做作,这种懒惰的灵魂对它来说真的很优雅

    【讨论】:

    • 问题是,任务说要使用 zipWith。我会试试看,你的方法对我有什么帮助。谢谢。
    • 您能否解释一下 e(L)is_list 和 is_function 何时发生以及为什么我们必须做出这种改变?我不明白。我认为它应该在没有 e() 的情况下工作,因为总是有一个惰性列表,这总是很有趣,但在某些情况下它必须有所不同。在哪里?
    • @user3556115,最开始是fibs == [1,1 | fun()],所以我们这里没有那么懒惰的列表。当您将[1,1 | fun()][H | L] 进行模式匹配时,您将得到H==1L == [1 | fun()]
    • L == [1 | fun()] 评估为列表?
    • e([1 | fun()]) 转到when is_list 案例
    猜你喜欢
    • 2021-05-16
    • 2014-05-19
    • 1970-01-01
    • 2013-04-29
    • 2018-05-11
    • 1970-01-01
    • 2017-07-08
    • 2015-06-05
    相关资源
    最近更新 更多