2017-09-13 111 views
1

我想要一个程序给出一个列表L,其中元素X出现三次,它返回一个包含它的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] 

附: 假设给定的列表不包含任何元素2,4或更多次。
所以,这是我的代码,但是当我提出问题时它返回false。任何建议纠正它,将不胜感激。

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

如果发生了四次?我们只需要找'1'吗?或者删除多次出现的* all *元素? –

+0

正如我在P.S中所写的,假设这种情况将不存在 – kindaExcited

+0

我会从* duck调试*开始:告诉(对你的橡皮鸭或者我们)你的谓词的目标是什么。你为什么在这里使用'append/3'?你为什么认为这是解决这个问题的好工具? –

回答

3

所以你说,那下面的查询应该会成功,但失败

?- 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必须发生在第二,第三和第五位。让我们来尝试,如果这是真的:

?- 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). 
+0

不错的地方在于,它应该在X元素可以定位的任何地方工作。你的建议幸运地工作,但你可以让我的工作呢?我的意思是追加/ 3。感谢您的帮助! – kindaExcited

+1

@ kindaExcited:这非常复杂:你至少需要6个(6)'append/3'目标 – false

+0

哦,我立即拒绝它。 – kindaExcited

0

附加/ 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). 
相关问题