我有一个包含数字的列表。 (例如: 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。
答案 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.