2011-05-20 88 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