2011-05-20 37 views
0

我想寫給出列表的Prolog的函數返回重複次數最多的在該列表中,像元素(S):最高紀錄在列表

[「一」,「一」, 'b','c','b']應該返回['a','b'] ['c','a','a','c','b','c',' b']應該返回['c'] etc ...

我想用另一個函數來做(它計數列表(countlist)上存在的東西的次數,但我不是得到一些幫助嗎?

listMax(In, Out) :- 
    listMax(In, Out, 0). 

listMax([H | L], [H | O], Max) :- 
    countlist(H, [H | L], N), 
    N > Max, 
    listMax(L, [H | O], N). 

listMax([H | L], O, Max) :- 
    countlist(H, [H | L], N), 
    <=(Max, N), 
    listMax(L, O, Max). 

listMax([], [], _Max). 

listMax([], _O, _Max). 
+1

我相信你的意思是's/function/predicate/g'。 (翻譯:他們在Prolog中被稱爲「謂詞」,而不是「功能」。) – 2011-05-21 03:34:02

回答

1

如何:

listmax(L, M):- 
listmax(L, [], [], M). 

listmax([], Seen, MMax, Max):- 
    MMax=[] -> Max=Seen ; listmax(MMax, [], [], Max). 
listmax([H|T], Seen, MMax, Max):- 
    (member(H, Seen) -> 
    listmax(T, Seen, [H|MMax], Max) ; 
    listmax(T, [H|Seen], MMax, Max)). 

這裏去該算法的一點解釋:

的想法是,通過列表中刪除這將產生一個新的列表中每個項目的第一次出現迭代。然後,遞歸地將相同的算法應用於這個新列表,直到我們得到一個空列表爲止。此時我們知道前面的列表是我們正在尋找的列表。

listmax/4的第二個子句是迭代子句,它檢查這是否是第一次看到該項目。這個謂詞的第二個參數保存了可見項目的列表。第三個參數收集剩餘的項目(第一次沒有看到的項目)。

listmax/4的第一個子句是基本情況。它在我們完成迭代列表時發揮作用。此時它會檢查剩餘項目列表是否爲空,在這種情況下,我們知道已列出的列表是我們正在查找的列表。否則,我們再次應用算法,但使用「剩餘列表」作爲輸入列表。

+0

這太好了。非常感謝你。現在我必須弄清楚它是如何工作的:D – Tiago 2011-05-21 01:00:56

+0

@Tiago:我已經更新了答案以提供關於它工作方式的詳細信息 – gusbro 2011-05-21 01:46:54

0

listmax(In,Out) :- 
     setof(A,member(A,In),L1), 
     findall([Count,A],(
        member(A,L1), 
        count(A,In,Count)), 
       L2), 
     max_1(L2,Max), 
     findall(A,member([Max,A],L2),Out). 

count(A,[],0). 
count(A,[A|R],X) :- 
     count(A,R,Y), 
     X is Y + 1. 
count(A,[_|R],X) :- 
     count(A,R,X). 

max_1(L,Max) :- 
     findall(A,member([A|_],L),L1), 
     max(L1,Max). 
+0

您正在測試哪個Prolog? SWI-Prolog抱怨'max_1/2'中的'max/2'謂詞調用,YAP恰好引發了一個飢餓的適應期。 – 2011-05-21 03:43:23