0

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

这个谓词接收一个列表并且必须生成结果列表

提前致谢

4

2 回答 2

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).
于 2012-12-29T11:41:18.813 回答
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).

它更干净,不是吗?member/2 它只被调用一次,这是一个很大的收获,并考虑使用memberchk /2 而不是 member/2。

但是该代码未能将最后一次出现标记为多个。

于 2012-12-29T12:48:50.917 回答