2014-03-18 31 views
-1

我一直在尝试写一些代码,需要值的列表,并删除其中仅在列表中一次,不重复的所有值:序言除去非复制

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]作为输出,因为最后一个和两个不被认为是重复的,因为它们不再是它们的成员尾巴,我无法检查它们是否是新列表的成员,因为它尚未实例化。

有没有办法解决这个问题?

谢谢。

+0

这是一个赋值/什么限制,你有 - 你允许使用例如。 nth1或其他列表/设置相关的内置插件,或者像findall/setof这样的收藏夹? – magus

+0

限制是算术和削减以外的其他内置函数。 – Qiri

+1

[Prolog只能删除唯一元素]的可能的重复(http://stackoverflow.com/questions/21971037/prolog-removing-unique-elements-only) – lurker

回答

-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

这是我会怎么做它:

  • 首先,列表成员的检查:

    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! 
    
  • 最后,公共接口谓词只是调用工人断言:

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

    注意:工作人员谓词以反向订单构建重复列表。如果顺序很重要,倒车列表很简单:

    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. 
        .      %