我在Prolog中遇到过这个问题。 问题是我想要计算出现在列表中的重复元素的数量, 我还希望在另一个带有1的列表中填写重复元素的每个外观,如果不重复则填写0,例如。
我有一个这样的清单:[420,325,420,582,135,430,582],结果应该是[1,0,1,1,0,0,1]。
我尝试了一些代码片段,这让我疯狂。
我试过的最后一个代码是:
count_duplicates([],[]).
count_duplicates([Head|Tail],[1|LS]):-
member(Head,Tail),
count_duplicates([Tail|Head],LS).
count_duplicates([Head|Tail],[0|LS]):-
\+ member(Head,Tail),
count_duplicates([Tail|Head],LS).
此谓词接收列表并必须生成结果列表
提前致谢
答案 0 :(得分:1)
你可以试试这个:
count_duplicate(In, Out) :-
maplist(test(In), In, Out).
test(Src, Elem, 1) :-
select(Elem, Src, Result),
member(Elem, Result).
test(_Src, _Elem, 0).
编辑没有地图列表,您可以
count_duplicate(In, Out) :-
test(In, In, Out).
test(_, [], []).
test(In, [Elem | T], [R0 | R]) :-
select(Elem, In, Rest),
( member(Elem, Rest) -> R0 = 1; R0 = 0),
test(In, T, R).
答案 1 :(得分:0)
我会使用一些可用的列表处理内置重写:
count_duplicates(L, R) :-
maplist(check(L), L, R).
check(L, E, C) :-
aggregate(count, member(E, L), Occurs),
( Occurs > 1 -> C = 1 ; C = 0 ).
用
?- count_duplicates([420,325,420,582,135,430,582],L).
L = [1, 0, 1, 1, 0, 0, 1].
关于你的代码,我认为终止是很简单的:
count_duplicates([],[]).
count_duplicates([Head|Tail],[1|LS]):-
member(Head,Tail),
count_duplicates(Tail,LS).
count_duplicates([Head|Tail],[0|LS]):-
\+ member(Head,Tail),
count_duplicates(Tail,LS).
注意我纠正了递归调用,并认为可以使用if .. then .. else ..构造以更有效的方式(源和运行时)完成。
count_duplicates([],[]).
count_duplicates([Head|Tail],[R|LS]):-
( member(Head,Tail) -> R = 1 ; R = 0 ),
count_duplicates(Tail,LS).
它更干净,不是吗?会员/ 2只召唤一次,这是一个很大的收获,
并考虑使用memberchk / 2而不是member / 2。
但是代码无法标记为最后一次出现的多次。