您离解决问题其实已经很接近了,但是需要更多的非确定性。简单来说,您需要找到一种使用更少切割的方式表达count_elt/3
,因为目前的做法可能会导致以下情况:
?- count_elt([a,b,a,a,c,b,d,e,a,f], Y, X).
Y = a,
X = 4.
你想要得到的是这样的:
?- count_elt([a,b,a,a,c,b,d,e,a,f], Y, X).
Y = a,
X = 4 ;
Y = b,
X = 2 ;
Y = c,
X = 1 ;
...
Y = f,
X = 1 ;
false.
从那里开始,你只需要找到具有最大值的解决方案,可以使用
setof/3
或逻辑表达式或使用
aggregate
库来实现。因此,首先修复
count_elt/3
,然后从那里开始。
编辑:一些一般性评论:1.您可以将
[H1|[H2|T]]
写为
[H1,H2|T]
,这样更清晰。2.
listMode/2
应该返回第二个位置的项目而不是计数。由于您需要计数来执行此过程,因此您可能需要创建一个
listMode/3
或
listMode/5
助手来在递归期间管理状态。
编辑:解决方案。由于@MaDu_LK已经决定展示解决方案,尽管这很可能是家庭作业,我想分享我的解决方案,使用@false的
重ified equality predicate:
count_of([], _, 0).
count_of([H|Rest], E, N1) :-
equality_reified(H, E, Bool),
count_of(Rest, E, N0),
(Bool == true -> N1 is N0 + 1 ; N1 = N0).
frequency(L, I, N) :-
sort(L, LSorted),
member(I, LSorted),
count_of(L, I, N).
mode(L, X) :-
frequency(L, X, NMax),
\+ (frequency(L, _, NBigger),
NMax < NBigger).
这种方法的性能要更好一些:
?- time(get_mode([a,b,c,a,b,c,a,a,b,c,a,d,b], X)).
X = a.
?- time(mode([a,b,c,a,b,c,a,a,b,c,a,d,b], X)).
X = a ;
false.
另一种解决方案也只产生一个模式,即使列表是多峰的:
?- get_mode([a,a,b,b,c], X).
X = a.
?- mode([a,a,b,b,c], X).
X = a ;
X = b ;
false.
思考的食品。