【问题标题】:Prolog beginner - reverse output listProlog初学者-反向输出列表
【发布时间】:2015-02-12 14:59:57
【问题描述】:

我是 Prolog 初学者,我正在寻找一种方法来反转此代码的输出。

fib(N, F) :- fib(N, 0, [1], F).
fib(0, _, A, A).
fib(N, A, [B|Bs], F) :- N1 is N - 1, Sum is A + B, fib(N1, B, [Sum,B|Bs], F).

代码计算N 的值的斐波那契数,并将结果打印到F

例如fib(4,X). 产生X=[5,3,2,1,1]。我想要的是X=[1,1,2,3,5](反向输出)。

我似乎不能把它变成这种格式,并保留它的尾递归属性。

感谢您的帮助

【问题讨论】:

    标签: list prolog reverse fibonacci


    【解决方案1】:

    如果你只是想在最后反转列表,使用reverse/2

    fib(N, F) :- fib(N, 0, [1], FRev), reverse(FRev, F).
    

    如果您想以相反的顺序构建列表,则必须重新考虑条款。一种解决方案是使用last/2append/3 将新元素放在累加器的末尾,而不是前面。


    返回第一个解决方案后,Prolog 尝试找到第二个解决方案,您可能会收到错误:

    ?- fib(5, F).
    F = [8, 5, 3, 2, 1, 1] ;
    ERROR: Out of global stack
    

    这是因为对于一个目标fib(0, ...) Prolog 使用第一条规则,但创建了一个选择点,然后它会回溯到它。从那时起,堆栈中充满了目标:fib(-1,...)fib(-2,...) 等。这些都不会满足。您应该在fib/4 的第一个子句中放置一个剪切运算符:

    fib(0, _, A, A):-!.
    

    所以它不会尝试使用第二条规则重新满足fib(0,...)

    ?- fib(5, F).
    F = [8, 5, 3, 2, 1, 1].
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2010-09-28
      相关资源
      最近更新 更多