您應該其他項目簡單地添加到匹配,使得如果H
是一個清單,以及,發生的次數是第一計:
find(Element,[],A,A).
find(Element, [Element|Tail], A, N) :-
!,
A1 is A + 1,
find(Element, Tail, A1, N).
find(Element,[[H|T]|Tail],A,N) :-
!,
find(Element,[H|T],A,R),
find(Element,Tail,R,N).
find(Element, [H|Tail], A, N) :-
find(Element, Tail, A, N).
通過之前放置的Element
(第二條)平等列表遞歸,你也可以在列表中搜索列表。換句話說:
find([1,2],[[1,2],[3],4,[1,2]])
將返回2
。
您使用剪切(!
)來防止Prolog回溯。
提示:不會在體內(Element = H
)如果可能的統一。只需在頭部重複使用相同的變量(find(Element,[Element|Tail],A,N)
)。許多Prolog編譯器能夠比第一種情況更好地優化後者。
提示:使用削減。您可以更頻繁地使用剪切,以防止Prolog從非確定性。例如,如果你在[5,1,2,5]
算5
的出現次數就可以拿出2
,1
和0
,因爲你從來沒有你的最後一句話,在指定H
是不等於到Element
。通過在前面的條款中進行剪切,Prolog解釋器將永遠不會對此進行回溯。
我認爲這是在您的中期一個錯誤:發現(元素,[H | T],A,T), 發現(元素,尾,T,N)。我得到你如何分割它,但最後和倒數第二個變量不應該與[H | T]的T重合。我對嗎? – user3614293 2014-10-06 05:20:04
確實,你應該使用另一個變量而不是'T'。對不起,但我希望你明白這一點?固定。 – 2014-10-06 05:25:54
@ user3614293:爲什麼要回溯到'find'謂詞。他們只會在一個'find'調用中阻止。由於沒有理由回溯(算法是「直截了當的」),所以沒有任何情況下這是有用的。 – 2014-10-06 06:16:17