列表中的最大出现次数

时间:2011-05-20 17:10:53

标签: prolog prolog-setof

我正在尝试编写一个Prolog函数,给定一个列表返回在该列表中重复多次的元素,如:

['a','a','b','c','b']应该返回['a','b'] ['c','a','a','c','b','c','b']应该返回['c'] 等...

我正在尝试使用另一个功能(计算列表中存在的某些内容的次数(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).

2 个答案:

答案 0 :(得分: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的第一个子句是基本情况。当我们完成遍历列表时,它就会发挥作用。此时它会检查剩余项目列表是否为空,在这种情况下,我们知道所见列表是我们要查找的列表。否则,我们再次应用算法,但使用“剩余列表”作为输入列表。

答案 1 :(得分: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).