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).
Другие вопросы по тегам