我试图找到最常见的列表项常见([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.
答案 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/3
和reduce/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)
保留logical-purity
使用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)
我可以给你一个高级答案:你可以对列表进行排序,然后一个接一个地计算项目相对容易,并更新到目前为止最常见的项目。