在列表中计算一个数字的出现次数

15
我正在使用Prolog编写一个程序,用于统计列表中某个数字的出现次数。
count([],X,0).
count([X|T],X,Y):- count(T,X,Z), Y is 1+Z.
count([_|T],X,Z):- count(T,X,Z).

这是输出结果

?- count([2,23,3,45,23,44,-20],X,Y).
X = 2,
Y = 1 ;
X = 23,
Y = 2 ;
X = 23,
Y = 1 ;
X = 3,
Y = 1 ;
X = 45,
Y = 1 ;
X = 23,
Y = 1 ;
X = 44,
Y = 1 ;
X = -20,
Y = 1 ;
false.

这是重复计算同一个数字

非常感谢您的帮助


1
请参考tcount/3以获取一个逻辑上纯粹的定义。 - false
3个回答

23

不要使用虚拟变量_,而是使用另一个变量X1,并确保它与X不一致。

count([],X,0).
count([X|T],X,Y):- count(T,X,Z), Y is 1+Z.
count([X1|T],X,Z):- X1\=X,count(T,X,Z).

请注意,第二个参数X需要被实例化。例如,count([2,23,3,45,23,44,-20],23,C)将使C与2一致。如果您想要每个元素的计数,请使用

:- use_module(library(lists)).

count([],X,0).
count([X|T],X,Y):- count(T,X,Z), Y is 1+Z.
count([X1|T],X,Z):- X1\=X,count(T,X,Z).

countall(List,X,C) :-
    sort(List,List1),
    member(X,List1),
    count(List,X,C).

然后,您会得到:

 ?- countall([2,23,3,45,23,44,-20],X,Y).
   X = -20,
   Y = 1 ? ;
   X = 2,
   Y = 1 ? ;
   X = 3,
   Y = 1 ? ;
   X = 23,
   Y = 2 ? ;
   X = 44,
   Y = 1 ? ;
   X = 45,
   Y = 1 ? ;
   no

至少对我而言,如果我只是用succ(Z, Y)替换Y is 1+Z,那么我在回溯时就不需要countall/3谓词来获取所有解决方案。您也应该尝试使用dif(X1, X)替换X1 \= X - user1812457

2
您还可以使用include谓词:
count(L, E, N) :-
    include(=(E), L, L2), length(L2, N).

0
ocr(X,[],0):- !.
ocr(X,[Element|Rs],V):- X = Element -> ocr(X,Rs,Ocr), V is 1+ Ocr; ocr(X,Rs,V).

我是这样做的。这只会给你一个答案并结束。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接