2014-10-06 77 views
1

我想了解累加器,所以我希望這個實現包含它們。 我想通過一個簡單的列表如何搜索。 這種計算給定元素的出現次數:Prolog查找列表中的元素與累加器

find(Element,[],A,A). 
find(Element, [H|Tail], A, N) :- Element = H, A1 is A + 1, 
find(Element, Tail, A1, N). 
find(Element, [H|Tail], A, N) :- find(Element, Tail, A, N). 

現在我該怎麼辦我使其成爲嵌套列表的工作?

回答

1

您應該其他項目簡單地添加到匹配,使得如果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的出現次數就可以拿出210,因爲你從來沒有你的最後一句話,在指定H不等於Element。通過在前面的條款中進行剪切,Prolog解釋器將永遠不會對此進行回溯。

+0

我認爲這是在您的中期一個錯誤:發現(元素,[H | T],A,T), 發現(元素,尾,T,N)。我得到你如何分割它,但最後和倒數第二個變量不應該與[H | T]的T重合。我對嗎? – user3614293 2014-10-06 05:20:04

+0

確實,你應該使用另一個變量而不是'T'。對不起,但我希望你明白這一點?固定。 – 2014-10-06 05:25:54

+0

@ user3614293:爲什麼要回溯到'find'謂詞。他們只會在一個'find'調用中阻止。由於沒有理由回溯(算法是「直截了當的」),所以沒有任何情況下這是有用的。 – 2014-10-06 06:16:17