鉴于prolog中的[1,2,3]通过反向积累得到[6,5,3]

时间:2009-11-17 22:38:33

标签: prolog

Q值。给定Prolog中的[1,2,3]通过反向积累得到[6,5,3]

我有开始代码:

accumalate([H],[H]).
accumalate([H1 | H2], [Hnew, H2]),
       Hnew is H1 + H2.

...

我正在寻找基本的Prolog解决方案。

4 个答案:

答案 0 :(得分:3)

我们不是来为你做功课。所以我们能做的最好的就是为您提供一些提示。所以问问自己这些问题:

  1. 这里的基本情况是什么(输出是立即输出的)?
    • 您有accumulate([N], [N]).,但空列表呢?
  2. 必须以什么顺序执行添加?
  3. 更具体地说,必须首先添加哪些元素?
  4. 除此之外,我可以告诉你,你可以用三个条款来解决这个问题。不需要其他谓词。祝你好运!

    奖金:您可能希望定义递归子句的头部,如下所示:

    accumulate([N|T], [N1,N2|T2]).
    

答案 1 :(得分:1)

这是我的看法:

accumulate([],[]).
accumulate([H|T], [H1|T1]):-
    sum([H|T],H1),
    accumulate(T,T1).
sum([],0).
sum([H|T],Y):-
    sum(T,Y1),
    Y is H + Y1.

如果您愿意,您当然可以使用内置的sumlist/2代替手工制作的sum/2

答案 2 :(得分:0)

完成基本实现后,请尝试在O(n)时间内解决此问题。我们的想法是从第一个元素开始,继续将其添加到辅助列表,直到原始列表为空。辅助列表是您需要的反向列表。

如果在递归步骤中附加两个列表,则最终会产生O(N ^ 2)复杂度。

答案 3 :(得分:0)

    ac([], 0, []).

    ac([H|T], ST, [ST|Res]) :-
        ac(T, X, Res),
        ST is H + X.

    accum(List, Res) :-
        ac(List, _, Res).

[trace]  ?- accum([1,2,3], X).
   Call: (6) accum([1, 2, 3], _G376) ? creep
   Call: (7) ac([1, 2, 3], _G458, _G376) ? creep
   Call: (8) ac([2, 3], _G461, _G454) ? creep
   Call: (9) ac([3], _G464, _G457) ? creep
   Call: (10) ac([], _G467, _G460) ? creep
   Exit: (10) ac([], 0, []) ? creep
   Call: (10) _G459 is 3+0 ? creep
   Exit: (10) 3 is 3+0 ? creep
   Exit: (9) ac([3], 3, [3]) ? creep
   Call: (9) _G456 is 2+3 ? creep
   Exit: (9) 5 is 2+3 ? creep
   Exit: (8) ac([2, 3], 5, [5, 3]) ? creep
   Call: (8) _G453 is 1+5 ? creep
   Exit: (8) 6 is 1+5 ? creep
   Exit: (7) ac([1, 2, 3], 6, [6, 5, 3]) ? creep
   Exit: (6) accum([1, 2, 3], [6, 5, 3]) ? creep
X = [6, 5, 3].