Опубликован: 12.02.2014 | Доступ: свободный | Студентов: 924 / 239 | Длительность: 11:22:00
Специальности: Программист
Лекция 7:

Списки. Предикаты высших порядков

< Лекция 6 || Лекция 7: 1234 || Лекция 8 >

7.5. Предикаты сортировки списка

Операцию сортировки списка выполняют предикаты sort и sortBy класса list. Сортировка выполняется в соответствии с алгоритмом слияния. По умолчанию список сортируется по возрастанию элементов:

L = sort([3, 6, 5, 1, 7, 8]). 

Для упорядочения списка по убыванию элементов используется предикат sort/2:

L = sort([3, 6, 5, 1, 7, 8], descending()).

Предикат sortBy выполняет сортировку в соответствии с заданным критерием. Например, при вызове

L = sortBy({(X, Y) = compare(X mod 3, Y mod 3)}, [3, 5, 7, 6, 1])

элементы списка будут упорядочены по возрастанию в соответствии со значением их остатка от деления на 3.

Критерий сортировки можно определить как в виде анонимного предиката (см. выше), так и в виде отдельного предиката (см. листинг 7.8).

class predicates
    comp : comparator{tuple{string, integer}}.
clauses
    comp(tuple(X, N), tuple(Y, N)) = compare(X, Y):- !.
    comp(tuple(_, N), tuple(_, K)) = compare(N, K).

    run():-
        write(list::sortBy(comp, [tuple("Маша", 18), tuple("Даша", 19),
                tuple("Глаша", 18), tuple("Паша", 17)])),
        _ = readLine().
Пример 7.8. Сортировка по заданному критерию

Список содержит сведения об именах и возрасте группы студентов. В результате применения предиката sortBy список упорядочивается по возрасту, а если возраст одинаковый, то по именам, в соответствии с лексикографическим порядком.

В следующей программе приведены примеры использования предикатов второго порядка класса list forAll/2, fold/3, removeDuplicatesBy/2, maximumBy/2 и decompose/2.

open core, console, list

class predicates
    comp : comparator{tuple{string, integer}}.
clauses
    comp(tuple(_, N), tuple(_, K)) = compare(N, K). % по возрасту

    run():- 
        L = [tuple("Маша", 18), tuple("Даша", 19),
                tuple("Глаша", 18), tuple("Паша", 17)],
        % вывод элементов списка
        forAll(L, {(tuple(X, N)):- write(X, " - ", N), nl}), nl,

        % суммарный возраст студентов
        write(fold(L, {(tuple(_, K), S) = K + S}, 0)), nl,

         % удаление студентов того же возраста, остаются по одному
        write(removeDuplicatesBy(comp, L)), nl,

        % самый старший по возрасту студент
        write(maximumBy(comp, L)), nl,

        % разбиение на группы по возрасту
        write(decompose(L, {(tuple(_, Age)) = Age})),
        _ = readLine().
Пример 7.9. Предикаты высших порядков

Упражнения

  1. По заданному списку проверьте, образуют ли его элементы арифметическую прогрессию.
  2. Определите операцию возвращения из списка слов всех слов-палиндромов. Для разбиения слов на списки символов используйте предикат string::toCharList/1.
  3. Определите операцию симметрической разности множеств, представленных списками.
  4. Определите операцию циклического сдвига элементов списка на заданное количество элементов

    • вправо;
    • влево.
  5. Сгенерируйте все перестановки списка, содержащие заданный подсписок.
  6. Сенерируйте все перестановки с повторениями, состоящие из заданного числа элементов, для данного множества элементов.
  7. Для заданного множества сгенерируйте сочетания с повторениями, состоящие из заданного числа элементов.
  8. Определите критерий сортировки элементов списка, состоящего из троек вида tuple(X, Y, Z), в которых хранятся имена (X), отчества (Y) и фамилии (Z) людей. Список должен быть упорядочен по фамилиям, при одинаковых фамилиях — по именам, при одинаковых именах и фамилиях — по отчествам.
  9. Найдите разбиение на классы эквивалентности множества элементов неотрицательных целых чисел. Два элементы эквивалентны, если они имеют одинаковые остатки при делении на n.
< Лекция 6 || Лекция 7: 1234 || Лекция 8 >
Жаныл Айкын
Жаныл Айкын
Rustam Inatov
Rustam Inatov

Доброго времени суток, подскажите пожалуйста, visual prolog examples, pie, vip7.5 - это все, где я могу скачать? (в смысле) может быть на сайте есть какой-то архив? Увы я не нашел его.

Подскажите, пожалуйста.

С уважением, Рустам.