List 序言:根据列表中的元素递增计数器
我试图根据列表中是否有某个元素来增加4个计数器。例如,假设:List 序言:根据列表中的元素递增计数器,list,recursion,prolog,counter,List,Recursion,Prolog,Counter,我试图根据列表中是否有某个元素来增加4个计数器。例如,假设: check_occurences(A,B,C,D,List) 以及: 我应该得到: A = 3; B = 3; C = 2; D = 2 我迄今为止的努力: check_occurences(A,B,C,D,List) :- helper(List,a,A), helper(List,b,B), helper(List,c,C), helper(List,d,D). helper([],_,A).
check_occurences(A,B,C,D,List)
以及:
我应该得到:
A = 3; B = 3; C = 2; D = 2
我迄今为止的努力:
check_occurences(A,B,C,D,List) :-
helper(List,a,A),
helper(List,b,B),
helper(List,c,C),
helper(List,d,D).
helper([],_,A).
helper([H|T],Elt,X) :- member(Elt,H), Count = X + 1, helper(T,Elt,Count).
helper([H|T],Elt,X) :- helper(T,Elt,X).
我的代码背后的想法是为每个计数器调用helper。如果Elt是X的一个成员,我递增计数器。如果不是,我使用第三个事实继续递归。当列表为空时,我停止。然而,问题是增加计数器
编辑:修复了代码中的错误 稍微概括一下您描述的问题:对于给定的列表,您想知道:
:- use_module(library(apply)).
:- use_module(library(lists)).
:- use_module(library(pairs)).
check_occurrences(Ls1, Ps3):-
maplist(sort, Ls1, Ls2),
append(Ls2, L),
map_list_to_pairs(count(L), L, Ps1),
sort(Ps1, Ps2),
transpose_pairs(Ps2, Ps3).
count(L, X, N):-
aggregate(count, member(X, L), N).
使用示例:
?- check_occurrences([[a,a,b,c],[a,b,c,d,e,f,g],[b,d,f,g],[a]], Counts).
Counts = [a-3, b-3, c-2, d-2, e-1, f-2, g-2].
如果是我,我可能会首先编写一个通用谓词来计算列表项的频率,如下所示:
frequencies( [] , Fs, Fs ) . % once the source list is exhausted, the frequency table is complete
frequencies( [X|Xs] , Ts, Fs ) :- % otherwise...
increment(X,Ts,T1) , % - increment the frequency count for X
frequencies(Xs,T1,Fs) % - and recurse down.
. %
increment( X , Ts , Fs ) :- % to increment the frequency list
append( Pfx , [X:C|Sfx] , Ts ) , % - If X is already a key in the list
!, % - cut off alternatives
C1 is C+1 , % - increment the count
append( Pfx , [X:C1|Sfx] , T1 ) % - put the list back together to create the new list.
. % otherwise...
increment( X , Fs , [X:1|Fs] ). % X is not in the list: add it.
然后,您的检查发生/3
谓词是简单且声明性的:
check_occurences(A,B,C,D,Xs) :- % to compute a frequency table,
frequencies( Xs , [], Fs ) , % - invoke the helper to compute the frequency table
frequency_of(a,Fs,A) , % - get the count for a
frequency_of(b,Fs,B) , % - get the count for b
frequency_of(c,Fs,C) , % - get the count for c
frequency_of(d,Fs,D) % - get the count for d
. % Easy!
frequency_of( _ , [] , 0 ) . % if the item is not a key in the list, the count is zero.
frequency_of( X , [X:N|_] , N ) :- % if the item is a key in the list, succeeed
. %
frequency_of( X , [Y:_|Fs] , N ) :- % otherwise....
X \= Y , % - assuming we haven't yet found the desired key
frequency_of(X,Fs,N) % - we recurse down
. %
使用
选择
而不是成员
不确定您为什么建议这样做。我只需要检查一个元素是否是列表的一部分。如果是,我将增加计数器。如果不是,则不要增加。然后我会转到列表中的下一个列表。哦,对不起,我以为你要数到双倍。(这样,[a,a,b]
被计数两次)。
check_occurences(A,B,C,D,Xs) :- % to compute a frequency table,
frequencies( Xs , [], Fs ) , % - invoke the helper to compute the frequency table
frequency_of(a,Fs,A) , % - get the count for a
frequency_of(b,Fs,B) , % - get the count for b
frequency_of(c,Fs,C) , % - get the count for c
frequency_of(d,Fs,D) % - get the count for d
. % Easy!
frequency_of( _ , [] , 0 ) . % if the item is not a key in the list, the count is zero.
frequency_of( X , [X:N|_] , N ) :- % if the item is a key in the list, succeeed
. %
frequency_of( X , [Y:_|Fs] , N ) :- % otherwise....
X \= Y , % - assuming we haven't yet found the desired key
frequency_of(X,Fs,N) % - we recurse down
. %