Существует способ (ну, бесконечные способы) решить эту проблему с помощью встроенных прологов, таких как sort/2
, findall/3
, member/2
, include/3
и length/2
:
?- List=[3,2,6,2,2,1,4,2,2,2,2,4,1,2,3,2,2,4,2,3,2],
sort(List, Uniq), % sort removing duplicate elements
findall([Freq, X], (
member(X, Uniq), % for each unique element X
include(=(X), List, XX), %
length(XX, Freq) % count how many times appears in List
), Freqs),
sort(Freqs, SFreqs), % sort (by frequency)
last(SFreqs, [Freq, MostCommon]), % last pair is the most common
length(List, ListLen),
Freq > ListLen/2. % is frequency greater than half list length?
Список = [3, 2, 6, 2, 2, 1, 4, 2, 2 | ...],
Uniq = [1, 2, 3, 4, 6],
Freqs = [[2, 1], [12, 2], [3, 3], [3, 4], [1, 6]],
SFreqs = [[1, 6], [2, 1], [3, 3], [3,4], [12, 2]],
Freq = 12,
MostCommon = 2,
ListLen = 21.
Зависит отНа какие ограничения наложил инструктор для решения упражнения, вам может потребоваться реализовать один или несколько из этих встроенных компонентов самостоятельно.
Другой способ, более эффективный, будет использовать msort/2
и затем создайте кодировку по длине прогона отсортированного списка, затем снова отсортируйте его и выберите элемент, представляющий наиболее часто встречающийся элемент.Сейчас я не могу понять, как выполнить кодирование по длине прогона без определения вспомогательных рекурсивных предикатов, поэтому вот оно:
count_repeated([Elem|Xs], Elem, Count, Ys) :-
count_repeated(Xs, Elem, Count1, Ys), Count is Count1+1.
count_repeated([AnotherElem|Ys], Elem, 0, [AnotherElem|Ys]) :-
Elem \= AnotherElem.
count_repeated([], _, 0, []).
rle([X|Xs], [[C,X]|Ys]) :-
count_repeated([X|Xs], X, C, Zs),
rle(Zs, Ys).
rle([], []).
, тогда получение наиболее распространенного элемента можно сделать с помощью:
?- List=[3,2,6,2,2,1,4,2,2,2,2,4,1,2,3,2,2,4,2,3,2],
msort(List, SList),
rle(SList, RLE),
sort(RLE, SRLE),
last(SRLE, [Freq, MostCommon]),
length(List, ListLen),
Freq > ListLen/2.
Список = [3, 2, 6, 2, 2, 1, 4, 2, 2 | ...],
SList = [1, 1, 2,2, 2, 2, 2, 2, 2 | ...],
RLE = [[2, 1], [12, 2], [3, 3], [3, 4],[1, 6]],
SRLE = [[1, 6], [2, 1], [3, 3], [3, 4], [12, 2]],
Freq = 12,
MostCommon = 2,
ListLen = 21.