繁体   English   中英

使用 prolog 消除列表元素的连续重复

[英]Eliminate consecutive duplicates of list elements with prolog

最初的问题是想出一种方法来获得以下内容

remove([a,a,a,b,q,q,q,q,e,e,e]),X)
X = [a,b,q,e]

我们可以通过沿着列表进行一次迭代来解决这个问题。 在列表中的任何一点,我们检查当前元素和下一个元素,如果它们相同,则忽略当前元素,否则,如果它们不同,则获取当前元素。

rm_dup([], []).
rm_dup([X], [X]).
rm_dup([X1, X2 | Xs], [X1 | Ys]) :-
    dif(X1, X2), rm_dup([X2|Xs], Ys).
rm_dup([X, X | Xs], Ys) :-
    rm_dup([X | Xs], Ys).

第一个和第二个子句是基本子句,其中没有重复的元素。 第三和第四条是递归规则。

在第三条我们 state 中,如果输入列表有两个值X1X2并且它们是不同的dif(X1, X2) ,则保留当前值。

在第四个子句中,如果我们有相同的连续值,那么我们忽略当前值。

第三和第四个子句是互斥的,因此为了使谓词具有确定性,最好将它们组合如下

rm_dup([X], [X]) :- !.
rm_dup([X1, X2 | Xs], Ys) :-
    dif(X1, X2) -> (rm_dup([X2 | Xs], Ys1), Ys = [X1 | Ys1]);
    rm_dup([X2 | Xs], Ys).

更好的是仅使用相等作为条件并翻转thenelse子句。

rm_dup([X], [X]) :- !.
rm_dup([X1, X2 | Xs], Ys) :-
    X1 = X2 ->  rm_dup([X2 | Xs], Ys);
    rm_dup([X2 | Xs], Ys1), Ys = [X1 | Ys1].

有点长,但这解决了它。

delete(_,[],[]).
delete(X,[X|T],R):- delete(X,T,R).
delete(X,[H|T],[H|R]) :- delete(X,T,R).

remove([],[]).
remove([H|T], [H|R]) :- 
    member(H,T),!,
    delete(H,T,R1),
    remove(R1,R).

remove([H|T],[H|R]):-
    remove(T,R).

您可以简单地使用排序。

首先:如果列表为空,则在基础 class 中停止。

第二:在第二个谓词中,取出列表并对其进行排序。 在 K 中显示答案。

remove_extras([],[]).
remove_extras([H|T],K):-
    sort([H|T], K).

?-remove_extras([a,a,a,b,q,q,q,q,e,e,e],X).
X = [a, b, e, q]

?-remove_extras([1,3,2,5,1,6,1,2,7],X).
X = [1, 2, 3, 5, 6, 7]

如果您不想使用排序,可以使用以下谓词: 删除重复项 检查多次存在的元素并将它们保留在列表中。

首先:基本情况说,如果列表是空的,则停止。

第二:第二个谓词检查剩余列表(成员)中是否存在元素,然后不要将其添加到最终列表中。

第三:第三个谓词说,如果元素不在剩余列表中,则将其添加到最终列表中。

remove_duplicates([],[]).
remove_duplicates([H | T], List) :-    
     member(H, T),
     remove_duplicates( T, List).

remove_duplicates([H | T], [H|T1]) :- 
     \+ member(H, T),
      remove_duplicates( T, T1).

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM