2014-03-18 30 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. 
        .      %