#list #prolog #max
#Список #пролог #макс
Вопрос:
я пишу функцию, которая возвращает true, если E является вторым по величине элементом из списка, особенно при попытке использовать библиотеку https://www.swi-prolog.org/pldoc/man?section=lists
вот так:
secLarg([], E).
secLarg([_], E).
secLarg([T], E) :- L is max_member(T, E), delete(T, L), max_member(E, L).
таким образом, используя какую-то композицию библиотечных функций max_member и delete, однако это решение не работает, поскольку max_member, по-видимому, возвращает только true / false, а не какой конкретный наибольший элемент. есть ли у вас какие-либо идеи о том, как я мог бы найти, является ли E вторым по величине элементом каким-либо образом, используя эти функции?
Ответ №1:
Проблема в том, что L is max_member(T, E)
это не имеет особого смысла. Предикат не возвращает значение: он либо завершается успешно, либо завершается неудачно. Он использует унификацию для унификации переменной с результатом.
Если вы используете [T]
для объединения с, вы будете объединять только со списками, содержащими ровно один элемент. В то время как вы, вероятно, хотите унифицировать списки с произвольным количеством элементов.
delete/3
также не изменяет список, он создает новый список, в котором он удалил самый большой элемент:
secLarg(Xs, E) :-
max_member(Lg, Xs),
delete(Xs, Lg, Xs1),
max_member(E, Xs1).
Также не имеет особого смысла писать secLarg([], E)
и secLarg([_], E)
, поскольку для таких списков нет второго по величине:
% secLarg([], E).
% secLarg([_], E).
secLarg(Xs, E) :-
max_member(Lg, Xs),
delete(Xs, Lg, Xs1),
max_member(E, Xs1).
Будьте осторожны, это delete/3
приведет к удалению всех элементов с заданным значением. Действительно:
?- delete([1,4,2,5,4], 4, R).
R = [1, 2, 5].
Поэтому, если есть список, в котором наибольшее значение встречается несколько раз, он не будет выбирать наибольшее значение (которое также является вторым по величине).