Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 在Prolog中保持顺序的同时删除重复项_List_Duplicates_Prolog_Logic_Predicate - Fatal编程技术网

List 在Prolog中保持顺序的同时删除重复项

List 在Prolog中保持顺序的同时删除重复项,list,duplicates,prolog,logic,predicate,List,Duplicates,Prolog,Logic,Predicate,我试图创建一个谓词,在保持列表的相对顺序的同时从列表中删除重复项。例如,[1,2,2,3,4,5,5,2]的列表应返回[1,2,3,4,5]。但是,我的代码只能删除连续的重复项,例如,不能删除末尾的2 remove_duplicates([],[]). remove_duplicates([H],[H]). remove_duplicates([H,H|T],[H|List]) :- remove_duplicates(T,List). remove_duplicates([H,X|T],[H|

我试图创建一个谓词,在保持列表的相对顺序的同时从列表中删除重复项。例如,[1,2,2,3,4,5,5,2]的列表应返回[1,2,3,4,5]。但是,我的代码只能删除连续的重复项,例如,不能删除末尾的2

remove_duplicates([],[]).
remove_duplicates([H],[H]).
remove_duplicates([H,H|T],[H|List]) :- remove_duplicates(T,List).
remove_duplicates([H,X|T],[H|T1]):- X\=H, remove_duplicates([X|T],T1).
我想到的另一种方法是使用member来查看尾部是否包含头部。然而,我能想到的解决这个问题的唯一方法是,如果头部是尾部的一部分,我将移除头部。然而,这将只保留数字的最后一个实例,并打破列表中数字的相对顺序

例如:

[1,2,2,3,4,5,5,2] 
[1,3,4,5,2]
当我真正想要的时候

[1,2,3,4,5]

您可以使用累加器:一个额外的参数,这里是一个最初为空的列表,当新元素出现时,该列表将增长。每次递归调用都会传递列表(或更新的副本)

例如:

remove_duplicates(LA, LB) :-
    remove_duplicates(LA, LB, []).

remove_duplicates([], [], _).
remove_duplicates([H|T], R, Seen) :-
    (  member(H, Seen)
    -> (R = S, Seen1 = Seen)
    ;  (R = [H|S], Seen1 = [H|Seen])
    ),
    remove_duplicates(T, S, Seen1).
当然,您可以使用比列表更有效的数据结构。我把它留作练习

?- remove_duplicates([1,2,2,3,4,5,5,2], L).
L = [1, 2, 3, 4, 5].