2013-04-07 78 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

相關問題