哪个列表项是最常见的

时间:2010-11-28 00:29:49

标签: prolog

我试图找到最常见的列表项常见([b,a,a,a,c,d,b,f,s,f,s,f,s,f,s,f,f ],R)所以结果应该是R = f, 我在想如果我们拿到列表,到列表的末尾取el = b,num1 = 1然后回到开头并比较b = b,num1 = num1 + 1否则a!= b然后如果num2 = num2 + 1,num1> num2 recursion else el = a或类似的东西,但我有一些困难将其转换为Prolog。

insert_sort对列表进行排序,但出于一些有趣的原因,如果我使用las(X,Y)(我覆盖原始的last/2),如果我使用last(X,Y),我会得到4-a。 ..

most_common([X|Y],J):-
    insert_sort([X|Y],[R|Rs]),             
    count_runs([R|Rs],G),
    las(G,J).

las([N-Y],Y).
las([_|T],Y):- las(T,Y).
las([_|Tail], Y) :- las(Tail, Y).

insert_sort(List,Sorted):-
   i_sort(List,[],Sorted).

i_sort([],Acc,Acc).
i_sort([H|T],Acc,Sorted):- 
    insert(H,Acc,NAcc),
    i_sort(T,NAcc,Sorted).

insert(X,[],[X]).     
insert(X,[Y|T],[Y|NT]):- X @> Y, insert(X,T,NT).
insert(X,[Y|T],[X,Y|T]):- X @=< Y.

4 个答案:

答案 0 :(得分:1)

这看起来像是家庭作业,所以我不打算给你一个完整的答案,但会建议你如何以一种特定的方式解决它,这不一定是最好的方式:

  • 将列表排序为排序顺序(如果足够好,按标准的术语顺序排序):查看sort/2例程。例如,[b,a,a,a,c,d,b]变为[a,a,a,b,b,c,d]

  • 获取排序列表并计算“运行”的大小,或许将[a,a,a,b,b,c,d]转换为[3-a,2-b,1-c,1-d](其中- / 2只是另一个术语)。例如,请考虑以下代码:


count_runs([E|Es], C) :-
      % defer to count_runs/3 with an initial count of element E
    count_runs(Es, 1-E, C).

  % return the final count for Y elements if none remain (base case)
count_runs([], N-Y, [N-Y]). 

count_runs([X|Es], N-Y, [N-Y|Rest]) :-
      % if X is not equal to Y, record the count and continue next run
    X \== Y, !,  
    count_runs([X|Es], Rest).

count_runs([_X|Es], N-Y, Rest) :-
      % else X equals Y; increment the counter and continue
    NPlusOne is N + 1,
    count_runs(Es, NPlusOne-Y, Rest).

  • 执行keysort/2之类的操作,按照键的值(即计数数字,将[3-a,2-b,1-c,1-d]转换为[1-c,1-d,2-b,3-a])对术语进行排序。然后,列表中最常出现的元素是具有相同键值的列表末尾的值(即,这里,这是最后一个术语a中的3-a)。一般来说,它们可能不止一个元素出现次数最多(与另一个元素相同)。
祝你好运。

答案 1 :(得分:1)

基于Prolog lambdas,我们使用元谓词tcount/3reduce/3,以及带有术语的平等谓词(=)/3

int x;
x=10;

示例查询:

?- mostcommon_in(X,[a,b,c,d,a,b,c,a,b]).
X = a ;
X = b ;
false.

请注意,这是单调(与之前的快速黑客版本不同)。瞧!

?- mostcommon_in(X,[A,B,C,D,A,B,C,A,B]), A=a,B=b,C=c,D=d.
X = a, A = a, B = b, C = c, D = d ;
X = b, A = a, B = b, C = c, D = d ;
false.

答案 2 :(得分:1)

保留 使用list_counts/2定义mostcommonitem_in/2,如下所示:

mostcommonitem_in(E,Xs) :-
   list_counts(Xs,Cs),                      % tag items with multiplicity
   maplist(\ (X-N)^(M-X)^(M is -N),Cs,Ps),  % prepare keysorting
   keysort(Ps,[Max-_|_]),                   % sort ascending by negated count
   member(Max-E,Ps).                        % pick most common ones

让我们运行查询!

?- mostcommonitem_in(X,[a,b,c,d,a,b,c,a,b]).
X = a ;
X = b ;
false.                                % OK

但是,它仍然是单调的吗?

?- mostcommonitem_in(X,[A,B,C,D,A,B,C,A,B]), A=a,B=b,C=c,D=d.
X = A, A = a, B = b, C = c, D = d ;
X = B, B = b, A = a, C = c, D = d ;
false.                                % OK: monotone

有速度吗? (与我在my previous answer to this question中展示的纯粹答案相比)

% OLD
?- length(Xs,5), time(findall(t,mostcommon_in(E,Xs),Ts)), length(Ts,N_sols).
% 854,636 inferences,    0.115 CPU in 0.115 seconds (100% CPU, 7447635 Lips)
N_sols = 71,   Xs = [_,_,_,_,_],     Ts = [t,t,t|...].    
?- length(Xs,6), time(findall(t,mostcommon_in(E,Xs),Ts)), length(Ts,N_sols).
% 4,407,975 inferences,  0.449 CPU in 0.449 seconds (100% CPU, 9813808 Lips)
N_sols = 293,  Xs = [_,_,_,_,_,_],   Ts = [t,t,t|...].
?- length(Xs,7), time(findall(t,mostcommon_in(E,Xs),Ts)), length(Ts,N_sols).
% 24,240,240 inferences, 2.385 CPU in 2.384 seconds (100% CPU, 10162591 Lips)
N_sols = 1268, Xs = [_,_,_,_,_,_,_], Ts = [t,t,t|...].

% NEW
?- length(Xs,5), time(findall(t,mostcommonitem_in(E,Xs),Ts)), length(Ts,N_sols).
% 4,031 inferences, 0.001 CPU in  0.002 seconds (93% CPU, 2785423 Lips)
N_sols = 71,   Xs = [_,_,_,_,_],     Ts = [t,t,t|...].    
?- length(Xs,6), time(findall(t,mostcommonitem_in(E,Xs),Ts)), length(Ts,N_sols).
% 17,632 inferences, 0.002 CPU in 0.002 seconds (100% CPU, 9194323 Lips)
N_sols = 293,  Xs = [_,_,_,_,_,_],   Ts = [t,t,t|...].    
?- length(Xs,7), time(findall(t,mostcommonitem_in(E,Xs),Ts)), length(Ts,N_sols).
% 82,263 inferences, 0.023 CPU in 0.023 seconds (100% CPU, 3540609 Lips)
N_sols = 1268, Xs = [_,_,_,_,_,_,_], Ts = [t,t,t|...].

答案 3 :(得分:-2)

我可以给你一个高级答案:你可以对列表进行排序,然后一个接一个地计算项目相对容易,并更新到目前为止最常见的项目。