2013-04-07 59 views
3

我只需要删除列表中的一个匹配项。其实并不重要,如果它是第一或最后。一场比赛需要被移除。删除列表中的第一个匹配项 - 序言

我很难理解为什么以下不能按预期工作。

deleteOne(_,[],[]). 

deleteOne(Term, [Term|Tail], Result) :- 
    deleteOne(Term, [], [Result|Tail]), !. 

deleteOne(Term, [Head|Tail], [Head|TailResult]) :- 
    deleteOne(Term, Tail, TailResult), !. 

输出

41 ?- deleteOne(5,[2,3,1,5,2,3,1],X). 
X = [2, 3, 1, 5, 2, 3, 1]. 

,当我与一个空字符串或一些随机的字符串替换术语它的工作原理。

deleteOne(Term, [Term|Tail], Result) :- 
    deleteOne("", Tail, Result), !. 

输出

41 ?- deleteOne(5,[2,3,1,5,2,3,1],X). 
X = [2, 3, 1, 2, 3, 1]. 

但我不认为这是有很多原因的最佳解决方案。不是为我目前的问题,但例如更长的名单。或者如果一个列表包含空字符串 - 不知道这是否可能在Prolog中。

为什么不通过第一个例子工作?还有什么其他解决方案?

回答

2

你的第一个不工作,因为这并没有太大的意义:

deleteOne(Term, [Term|Tail], Result) :- 
    deleteOne(Term, [], [Result|Tail]), !. 

这意味着下一个结果必须有当前结果作为它的头。

一个更好的解决办法是这样的:

delete_one(_, [], []). 
delete_one(Term, [Term|Tail], Tail). 
delete_one(Term, [Head|Tail], [Head|Result]) :- 
    delete_one(Term, Tail, Result). 

如果你希望它是决定性的,第二条增加一个切口。因为它可以这样做:

?- delete_one(2, [1, 2, 3, 1, 2, 3], X). 
X = [1,3,1,2,3] ? ; 
X = [1,2,3,1,3] ? ; 
X = [1,2,3,1,2,3] ? ;  
no 
+0

我现在看到我犯了我的错误。递归仍然有时让我感到困惑,并且做愚蠢的想法。感谢您的澄清并提供更好的解决方案。 – 2013-04-07 00:20:20

相关问题