Predsort/3, как msort/2
Я хотел бы знать, возможно ли использовать predsort/3
без потери повторяющихся значений? Если нет, то как мне отсортировать этот список терминов?
Текущая функция сортировки:
compareSecond(Delta, n(_, A, _), n(_, B, _)):-
compare(Delta, A, B).
Результат:
predsort(compareSecond, [n(3, 1, 5), n(0, 0, 0), n(8, 0, 9)], X).
X = [n(0, 0, 0), n(3, 1, 5)].
Вы видите, этот термин n(8,0,9)
ушел и это не то, что мне нужно.
2 ответа
Решение
predsort
удалит дубликаты, но оставляет предикату сравнения определить, какие элементы являются дубликатами. Адаптируй свой compareSecond
Предикат также сравнивает первый и третий аргументы с полученными функторами, если второй аргумент сравнивается равным.
В качестве альтернативы, переключитесь на msort
:
?- maplist(swap_1_2, [n(3, 1, 5), n(0, 0, 0), n(8, 0, 9)], Swapped),
| msort(Swapped, SortedSwapped),
| maplist(swap_1_2, Sorted, SortedSwapped).
% snip
Sorted = [n(0, 0, 0), n(8, 0, 9), n(3, 1, 5)] .
где определение swap_1_2
оставлено в качестве упражнения для читателя.
Если вас не беспокоит дальнейшая сортировка дубликатов, это простое добавление предотвращает их удаление.
compareSecond(Delta, n(_, A, _), n(_, B, _)):-
A == B;
compare(Delta, A, B).