我正在寻找列表中最常见的项目,但我得到了很多随机结果。不知道为什么。
这是我的代码:
find_most_common([], []).
find_most_common(List, E) :-
msort(List, [H|T]),
find_most_common(T, H, H, 1, 0, E).
find_most_common([], H, _, C1, C2, H) :-
C1 >= C2.
find_most_common([], _, X, C1, C2, X) :-
C1 < C2.
find_most_common([H|T], H, L, C1, C2, E) :-
find_most_common(T, H, L, C1 + 1, C2, E).
find_most_common([X|T], H, L, C1, C2, E) :-
(
C1 > C2 -> find_most_common(T, X, H, 1, C1, E) ;
find_most_common(T, X, L, 1, C2, E)
).
这是我得到的结果:
?- find_most_common([a,b,b,a,a], E).
E = a ;
E = a ;
E = b ;
E = a ;
E = b ;
E = a ;
E = b ;
E = b ;
false.
我应该这样做:
?- find_most_common([a,b,b,a,a], E).
E = a ;
false.
答案 0 :(得分:1)
你需要告诉Prolog停止使用“cut”搜索替代品。
例如,如果您在此子句中添加以下“cut”...
find_most_common([H|T], H, L, C1, C2, E) :- !,
find_most_common(T, H, L, C1 + 1, C2, E).
它只能为您提供的输入找到一个答案。
在这种情况下应该发生什么?
find_most_common([a,a,a,b,b,b],E)。
它应该返回a还是b?它目前将返回b。
如果您使用trace.
运行程序,当您要求重做时,您可以看到哪个子句正在“重做”......
(这不加额外的切割)
[trace] 3 ?- find_most_common([a,b,b,a,a], E).
Call: (6) find_most_common([a, b, b, a, a], _G3171) ? creep
Call: (7) msort([a, b, b, a, a], [_G3251|_G3252]) ? creep
Exit: (7) msort([a, b, b, a, a], [a, a, a, b, b]) ? creep
Call: (7) find_most_common([a, a, b, b], a, a, 1, 0, _G3171) ? creep
Call: (8) find_most_common([a, b, b], a, a, 1+1, 0, _G3171) ? creep
Call: (9) find_most_common([b, b], a, a, 1+1+1, 0, _G3171) ? creep
Call: (10) 1+1+1>0 ? creep
Exit: (10) 1+1+1>0 ? creep
Call: (10) find_most_common([b], b, a, 1, 1+1+1, _G3171) ? creep
Call: (11) find_most_common([], b, a, 1+1, 1+1+1, _G3171) ? creep
Call: (12) 1+1>=1+1+1 ? creep
Fail: (12) 1+1>=1+1+1 ? creep
Redo: (11) find_most_common([], b, a, 1+1, 1+1+1, _G3171) ? creep
Call: (12) 1+1<1+1+1 ? creep
Exit: (12) 1+1<1+1+1 ? creep
Exit: (11) find_most_common([], b, a, 1+1, 1+1+1, a) ? creep
Exit: (10) find_most_common([b], b, a, 1, 1+1+1, a) ? creep
Exit: (9) find_most_common([b, b], a, a, 1+1+1, 0, a) ? creep
Exit: (8) find_most_common([a, b, b], a, a, 1+1, 0, a) ? creep
Exit: (7) find_most_common([a, a, b, b], a, a, 1, 0, a) ? creep
Exit: (6) find_most_common([a, b, b, a, a], a) ? creep
E = a ;
Redo: (10) find_most_common([b], b, a, 1, 1+1+1, _G3171) ? creep
Call: (11) 1>1+1+1 ? creep
Fail: (11) 1>1+1+1 ? creep
Redo: (10) find_most_common([b], b, a, 1, 1+1+1, _G3171) ? creep
Call: (11) find_most_common([], b, a, 1, 1+1+1, _G3171) ? creep
Call: (12) 1>=1+1+1 ? creep
Fail: (12) 1>=1+1+1 ? creep
Redo: (11) find_most_common([], b, a, 1, 1+1+1, _G3171) ? creep
Call: (12) 1<1+1+1 ? creep
Exit: (12) 1<1+1+1 ? creep
Exit: (11) find_most_common([], b, a, 1, 1+1+1, a) ? creep
...etc...
答案 1 :(得分:1)
这是另一种方法:迭代元素并查找是否更频繁地满足另一个元素(注意比较是针对整数):
my-member([X], X).
my-member([_|T], X) :- my-member(T, X).
count-occur([H], X, 0) :- H =\= X.
count-occur([X], X, 1).
count-occur([H|T], X, C) :-
( H =:= X, count-occur(T, X, C1), C is C1 + 1 );
( H =\= X, count-occur(T, X, C) ).
most-common(L, E) :-
my-member(L, E),
count-occur(L, E, C),
not((my-member(L, Y, C1), Y =\= E, C > C1 )).
答案 2 :(得分:0)
这是我的方法
most_common([], []).
most_common([H|T], M) :-
nb_occurences([H|T], [], N),
sort(N, RS),
reverse(RS, [Max:I|S]),
member(Max:M, [Max:I|S]).
nb_occurences([], L, L).
nb_occurences([H|T], L, N) :-
( select(I:H, L, L2) ->
J is I + 1
;
J is 1,
L2 = L
),
nb_occurences(T, [J:H|L2], N).
首先,我们使用nb_occurences/3
来构建对Occurences:Element
对的列表。然后我们对这些对进行排序并将最后一对出现,以选择我们使用member/2
检索的正确输出。