计算prolog中的重复元素

时间:2012-12-29 11:10:54

标签: prolog

我在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).

此谓词接收列表并必须生成结果列表

提前致谢

2 个答案:

答案 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。

但是代码无法标记为最后一次出现的多次。