在列表中计算大于2的项目

时间:2018-05-09 18:05:29

标签: prolog

我有一个包含数字的列表。 (例如: L = [1,0,0,1,3,2,3] )。

我试图创建一个带有此列表的谓词并返回一个整数E,它是任何大于2的数字的出现次数。

例如在上面的例子中,让我们说谓词叫做 pred / 2 , 那么 pred([1,0,0,1,3,2,3],E)会返回 E = 2 ,因为唯一大于2的数字是3这个数字出现了2次。

如果有2个或更多不同的数字大于2,例如: L = [0,1,1,2,3,4,5,6,6] 会必须返回5,因为有5个数字大于2。

2 个答案:

答案 0 :(得分:0)

我们可以使用辅助谓词和累加器 count / 3 。我们将使用已经遇到的值大于2的累加器存储计数。

% we initialize accumulator with 0
count(L, Count) :- count2(L, 0, Count).

% for empty list there is no more elements grater than 2
count2([], Acum, Acum).

% otherwise we have two consider two cases
count2([H|T], Acum, Out) :-
( H > 2 ->
    Acum2 is Acum + 1,
    count2(T, Acum2, Out)
;
    count2(T, Acum, Out)
).

答案 1 :(得分:0)

我想出最好的方法是使用高阶谓词编写一些现代的序言:

pred(List, Count) :-
    maplist([In,Out] >> (In>2 -> Out=1 ; Out=0), List, BinaryList),
    foldl([In1,In2,Out] >> (Out is In1+In2), BinaryList, 0, Count).

通过将每个项目映射到1(如果它大于2),否则为0,然后将1和0相加来工作。

一些测试:

?- pred([1,0,0,1,3,2,3], Count).
Count = 2.

?- pred([0,1,1,2,3,4,5,6,6], Count).
Count = 5.

奖励:这可以推广到计算有多少元素使谓词成立:

count(Pred, List, Count) :-
    maplist([In,Out] >> (call(Pred,In) -> Out=1 ; Out=0), List, BinaryList),
    foldl([In1,In2,Out] >> (Out is In1+In2), BinaryList, 0, Count).

这样我们就可以将(X>2)作为参数传递:

?- count([X] >> (X>2), [1,0,0,1,3,2,3], Count).
Count = 2.

或其他:

?- count([X] >> (X<2), [1,0,0,1,3,2,3], Count).
Count = 4.