因此,我编写了一个程序,该程序以2个整数和一个整数列表的形式从.txt文件中读取输入:第一个整数是列表的长度,第二个是不同元素的数量,列表就是有问题的列表。
然后我想为元素创建一个频率列表,如下所示:
List = [1, 2, 3, 1, 3, 2, 3, 1],
FreqList = [3, 2, 3].
这是我的代码:
% Create random list
createList(List) :-
length(List, 10),
maplist(random(0,4), List).
% Count the frequency of an element:
countElement(_, [], 0) :- !.
countElement(_, [], _).
countElement(Element, [Element|Tail], Counter) :-
countElement(Element, Tail, Counter2),
Counter is Counter2 + 1.
countElement(Element, [_|Tail], Counter) :-
countElement(Element, Tail, Counter).
% Create frequency list:
createFreqList(_, _, Numbers, [], CurrentNumber) :-
Numbers = CurrentNumber.
createFreqList(List, Length, Numbers, [Head|Tail], CurrentNumber) :-
Numbers \= CurrentNumber,
countElement(CurrentNumber, List, Head),
CurrentNumber2 is CurrentNumber + 1,
createFreqList(List, Length, Numbers, Tail, CurrentNumber2).
frequency(List, FreqList) :-
createList(List),
Numbers2 is 4,
createFreqList(List, 10, Numbers2, FreqList, 1).
因此,在第一次执行时,程序运行正常,并输出正确的频率列表。但是,如果我输入“;”,而不是给我“ false”,它会再次运行,输出错误的频率列表,并且只要我按“;”,它就会重复一次。
答案 0 :(得分:0)
以防万一您不想重新发明轮子。
有一个称为库(集合)的准标准。但是库(聚合)也可以在ISO核心标准bagof / 3之上实现,这也可以帮助您:
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.6)
?- aggregate(count, member(X,[1, 2, 3, 1, 3, 2, 3, 1]), R).
X = 1,
R = 3 ;
X = R, R = 2 ;
X = R, R = 3.
?- bagof(hit, member(X,[1, 2, 3, 1, 3, 2, 3, 1]), L), length(L, R).
X = 1,
L = [hit, hit, hit],
R = 3 ;
X = R, R = 2,
L = [hit, hit] ;
X = R, R = 3,
L = [hit, hit, hit].
或在另一个Prolog系统中:
Jekejeke Prolog 3, Runtime Library 1.3.7 (May 23, 2019)
?- use_module(library(advanced/aggregate)).
% 3 consults and 0 unloads in 110 ms.
Yes
?- use_module(library(basic/lists)).
% 0 consults and 0 unloads in 0 ms.
Yes
?- aggregate(count, member(X,[1, 2, 3, 1, 3, 2, 3, 1]), R).
X = 1,
R = 3 ;
X = 2,
R = 2 ;
X = 3,
R = 3
?- bagof(hit, member(X,[1, 2, 3, 1, 3, 2, 3, 1]), L), length(L, R).
X = 1,
L = [hit,hit,hit],
R = 3 ;
X = 2,
L = [hit,hit],
R = 2 ;
X = 3,
L = [hit,hit,hit],
R = 3
答案 1 :(得分:0)
我可能会做这样的事情:
frequencies(Xs, Fs) :-
msort(Xs,Sorted),
glob( Sorted, [], Fs ).
glob( [], Fs, Fs ).
glob( [X|Xs], [X:N|Ts], Fs ) :-
!,
N1 is N+1,
glob(Xs, [X:N1|Ts], Fs ).
glob( [X|Xs], Ts, Fs ) :-
glob(Xs, [X:1|Ts], Fs).
使用msort/2
按顺序排列列表。结果列表按键值{[ 3:123, 2:25, 1:321 ]
降序排列。
您还可以执行以下操作:
frequencies(Xs, Fs) :- frequencies( Xs, [], Fs ).
frequencies( [], Fs, Fs ).
frequencies( [X|Xs], Ts, Fs ) :-
tote( X, Ts, T1),
frequencies(Xs, T1, Fs).
tote( X, Ts, Fs ) :-
append( Pfx, [X:N|Sfx], Ts),
!,
N1 is N+1,
append( Pfx, [X:N1|Sfx], Fs).
tote( X, Ts, [X:1|Ts] ).
我怀疑原始列表的一次性排序可能比重复扫描累加器列表更快。