Prolog删除非重复项

时间:2014-03-18 18:03:19

标签: list prolog

我一直在尝试编写一些带有值列表的代码,并删除仅列在列表中的所有值,非重复项:

dbltaker([], []).
dbltaker([H | X], Y):-
        \+mem(H, X),
    dbltaker(X, Y).
dbltaker([H | X], [H | Y]):-
    mem(H, X), !,
    dbltaker(X, Y).
dbltaker([H | X], [H | Y]):-
    mem(H, Y),
    dbltaker(X, Y).
mem(H, [H | _]).
mem(H, [_ | T]):-
    mem(H, T).

我遇到的麻烦是,在将非重复移动到另一个列表之后,它的重复不再是重复,因此不会移动到列表中。例如,列表[1,1,1,2,2,3]给出[1,1,2]作为输出,因为最后一个和两个不被视为重复,因为它们不再是它们的成员尾巴,我无法检查它们是否是新列表的成员,因为它尚未实例化。

有解决方法吗?

感谢。

2 个答案:

答案 0 :(得分:-1)

我认为更简单的方法应该是传递给原始列表,以便能够检查元素何时重复。

dbltaker(L, R) :- dbltaker(L, L, R).

dbltaker([], _L, []).
dbltaker([H|T], L, [H|R]) :- at_least_2(H, L), !, dbltaker(T, L, R).
dbltaker([_|T], L, R) :- dbltaker(T, L, R).

服务谓词at_least_2(H, L)可以很容易地实现......

答案 1 :(得分:-1)

我就是这样做的:

  • 首先,检查列表成员资格:

    exists_in( A , [A|_] ) :- ! .
    exists_in( A , [_|B] ) :- exists_in(A,B) .
    
  • 然后是条件添加。如果X不包含在Y中,则将X添加到Y,得到Z:

    add_if_not_exists( X , Z , Z     ) :-  exists(X,T) , ! .
    add_if_not_exists( X , Y , [X|Y] ) .
    
  • 使用累加器(播种到空列表[])来构建一组不同元素的工作谓词,它完成了艰苦的工作:

    dedupe( []     , Z , Z ) .   % if the source list is exhausted, we're done: the accumulator is the set of distinct list members.
    dedupe( [X|Xs] , Y , Z ) :-  % otherwise...
      add_if_not_exists(X,Y,T) , % - add X to the accumulator if it's not already there.
      dedupe(Xs,T,Z)             % - and recurse down.
      .                          % Easy!
    
  • 最后,公共接口谓词只调用worker谓词:

    dedupe( Xs, Ys ) :-     % dedupe a list
      dedupe( Xs, [] , Ys ) % by invoking the helper predicate with the accumulator seeded with the empty set.
      .                     %
    

    注意: worker谓词以逆序构建重复数据删除列表。如果订单很重要,那么撤销列表是微不足道的:

    rev( []     , [] ) .
    rev( [X|Xs] , Rs ) :- rev( Xs , [X|Rs] ) .
    

    只需修改公共接口即可进行撤消:

    dedupe1( Xs, Ys ) :-     % dedupe a list
      dedupe( Xs, [] , T ) , % by invoking the helper predicate with the accumulator seeded to the empty set.
      rev(T,Ys)              % and reversing the result.
      .                      %