删除元素的第2次和第3次出现

时间:2017-09-13 13:19:59

标签: prolog

我想创建一个程序,给出一个列表L,其中元素X出现3次,它返回NL列表,只包括它一次。 例如,这个问题

?- erase([1,2,3,1,6,1,7],1,NL).

应该返回

NL = [1,2,3,6,7]  or  NL = [2,3,1,6,7]  or  NL = [2,3,6,1,7]

P.S。 假设给定列表不包括任何元素2,4次或更多次 所以,这是我的代码,但是当我提出问题时它返回false。任何纠正它的建议都将受到赞赏。

erase([],_,[]).
erase(L,X,NL):-
                append(A,[X,B,X,C,X,D],L),
                append(A,[X,B,C,D],NL).

2 个答案:

答案 0 :(得分:4)

所以你说,以下查询应该成功,但是失败

?- erase([1,2,3,1,6,1,7],1,NL).
false.

即使是以下概括也失败了:

?- erase([1,2,3,1,6,1,7],E,NL).
false.

让我重新制定一下以便于访问:

?- L = [1,2,3,1,6,1,7], erase(L,E,NL).
false.

所以我们现在必须进一步概括这个清单。我可以按元素尝试这个元素,但我更喜欢第一个:

?- L = [_,_,_,_,_,_,_], erase(L,E,NL).
L = [_2528, E, _2540, E, _2552, E, _2564],
NL = [_2528, E, _2540, _2552, _2564] ;
false.

这是唯一的答案。它告诉我们E必须恰好发生在第2,第3和第5位置。如果这是真的,那就试试吧:

?- erase([0,1,0,1,0,1,0],1,NL).
NL = [0, 1, 0, 0, 0] ;
false.

所以你的解决方案有效 - 有时候。你好像想要:

erase(L, X, NL) :-
   phrase(
      ( seq(Any1), [X], seq(Any2), [X], seq(Any3), [X], seq(Any4) ), L),
   phrase(
      ( seq(Any1),      seq(Any2),      seq(Any3), [X], seq(Any4) ), NL).

seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).

答案 1 :(得分:0)

append / 2在处理多个列表时有很大帮助:

erase(L,E,R) :-
    append([A,[E],B,[E],C,[E],D],L),
    select([E],[X,Y,Z],[[],[]]),
    append([A, X, B, Y, C, Z, D],R).
相关问题