如何将列表中的每一位数相加 - Prolog?

时间:2016-06-12 08:48:18

标签: list prolog clpfd

给定一些整数列表,我想用Prolog计算列表中每个第二个元素的总和?

E.g:

[1,2,3,4] => [2+4] = 6

3 个答案:

答案 0 :(得分:3)

虽然solution by @SeekAndDestroy没问题,但我想补充一下:

  1. 用于声明性整数算术。

    :- use_module(library(clpfd)).
    
  2. 使用第一个参数索引来避免无用的选择点。

    list_evens_odds([], [], []).
    list_evens_odds([X|Xs], [X|Es], Os) :-
       list_evens_odds(Xs, Os, Es).
    
  3. 就是这样!

    总结其他所有项目(从第2项开始),查询如下:

    ?- list_evens_odds([1,2,3,4], _, Zs), sum(Zs, #=, Sum).
    Zs = [2,4], Sum = 6.
    

答案 1 :(得分:2)

有几种方法可以实现这一目标,但是为了让您了解使用累加器来跟踪当前总和的简单递归解决方案:

% Sets accumulator to 0 for convenience
sum_second(List,Result) :- sum_second(List,0,Result).

sum_second([],A,A).             % Empty list
sum_second([_],A,A).            % One element left in list
sum_second([_,H|T],A,R) :-      % Accumulate sum of second element
    A2 is A+H,
    sum_second(T,A2,R).

使用示例:

?- sum_second([1],R).
R = 0.
?- sum_second([1,2],R).
R = 2.
?- sum_second([1,2,3,4,5,6],R).
R = 12.

答案 2 :(得分:1)

我会使用库(aggregate):

sum_every_nth1(L,I,S) :- aggregate(sum(X), P^(nth1(P,L,X), P mod I=:=0), S).

?- sum_every_nth1([1,2,3,4],2,S).
S = 6.

sum_every_nth1 / 3基于'关系' nth1 / 3的行为,它将列表中的位置(样本中的P)绑定到元素。因此,当使用P free调用时,它会将它绑定到连续的索引。然后,目标P mod I=:=0过滤掉不满足要求的索引(导致连接失败 - 逗号表示AND)。

修改

library(aggregate)有一个特定的目的,即提供SQL中可用的缺失聚合运算符。为了处理乘法,我建议将“提取”分开。来自对它们执行的实际操作的元素:

every_nth1(L,I,Ns) :- findall(X, (nth1(P,L,X),P mod I=:=0), Ns).

mul_every_nth1(L,I,M) :-
    every_nth1(L,I,[N0|Ns]),
    foldl([N,M0,M1]>>(M1 is M0*N),Ns,N0,M).

every_nth1 / 3获取所选元素的列表,foldl / 4需要将它们相乘。

?- mul_every_nth1([1,2,3,4],2,M).
M = 8.

修改

如果您缺少图书馆(yall):

multiply(N,M0,M1) :- M1 is M0*N.

mul_every_nth1(L,I,M) :-
    every_nth1(L,I,[N0|Ns]),
    foldl(multiply,Ns,N0,M).