【问题标题】:Removing Duplicates while maintaining order in Prolog在 Prolog 中保持顺序的同时删除重复项
【发布时间】:2020-04-23 20:54:38
【问题描述】:

我正在尝试创建一个谓词,该谓词从列表中删除重复项,同时保持其相对顺序。例如,[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 来查看 Tail 是否包含 Head。但是,我能想到以这种方式解决它的唯一方法是,如果 head 是 tail 的成员,我会移除头部。但是,这将仅保留数字的最后一个实例并破坏列表中数字的相对顺序。

例如:

[1,2,2,3,4,5,5,2] 
[1,3,4,5,2]

当我真正想要的时候

[1,2,3,4,5]

【问题讨论】:

    标签: list duplicates prolog logic predicate


    【解决方案1】:

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

    例如:

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

    当然,您可以使用比列表更有效的数据结构。我把它留作练习。

    【讨论】:

      猜你喜欢
      • 2010-12-05
      • 2012-07-21
      • 2021-04-25
      • 2011-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-03
      相关资源
      最近更新 更多