2012-01-31 38 views
10

我写序言中的一个程序,计算一个列表计数一批出现的次数在列表

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'](http://stackoverflow.com/a/29960878/772868)。 – false 2015-06-09 08:35:25

回答

14

取而代之的是虚拟的VARI能_只需使用另一个变量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)将统一下用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 
+0

胖胖,多谢,很完美 – Ratzo 2012-02-01 16:33:40

+0

至少对我来说,如果我用'succ(Z,Y)'替换'Y是1 + Z',那么我不需要'countall/3'谓词完全可以在回溯时获得所有解决方案。你也应该尝试用'dif(X1,X)'替换'X1 \ = X'。 – 2016-01-13 08:28:48

+0

请参阅[这个答案](http://stackoverflow.com/a/34738970/1812457) – 2016-01-13 08:42:07

0

您还可以使用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). 

我做的那样。这给你只有一个答案,并完成。