Написать функцию разности множеств - Lisp
Формулировка задачи:
Привет всем!
Задача:
По началу было понятно, что при вызове функции (f '(1 2 1 2 1 3) '(5 3 3 1 2 2)), первый элемент 1-го списка сравнивался с первым элементом второго списка. Типа, если (i1>j1), то i1-j1, иначе если (i1<j1) идем дальше (проверяем n-ый элемент i-го и j-го списков), иначе 0. Получается так:
1<5 --> идем дальше
2<3 --> идем дальше
1<3 --> идем дальше
2>1 --> 2-1 = 1
1<2 --> идем дальше
3>2 --> 3-2 = 1
И получили в результате (1 1).
Со вторым случаем уже сложнее, если следовать логике 1-го примера, то получится (4 1 2 1) и, как я понимаю, он складывает два значения? Но про сложение ничего не написано в задании. Как быть? И как можно это реализовать (без лямбды)?
Пусть si и s2 - "множества с повторяющими элементами". Определите функцию (f si s2). которая вычисляет "разность множеств". Так, например, вызов
(f '(1 2 1 2 1 3) '(5 3 3 1 2 2)) должен давать результат (1 1); а вызов (f '(5 3312 2)'(12121 3)) должен давать результат (5 3).
Решение задачи: «Написать функцию разности множеств»
textual
Листинг программы
(defun task (s1 s2) (cond ((null s1) nil) ((member (car s1) s2) (task (cdr s1) (removef (car s1) s2))) (t (cons (car s1) (task (cdr s1) s2))))) ==> task (task '(1 2 1 2 1 3) '(5 3 3 1 2 2)) ==> (1 1) (task '(5 3 3 1 2 2) '(1 2 1 2 1 3)) ==> (5 3)
Объяснение кода листинга программы
В коде определена функция task, которая принимает два аргумента s1 и s2. Функция проверяет, является ли s1 пустым списком. Если это так, то возвращается nil. В противном случае функция проверяет, есть ли первый элемент s1 в списке s2. Если это так, то функция рекурсивно вызывает себя с аргументами (cdr s1) и (removef (car s1) s2). Если это не так, то функция добавляет первый элемент s1 к результату вызова функции task с аргументами (cdr s1) и s2. Значения переменных: s1 - '(1 2 1 2 1 3) s2 - '(5 3 3 1 2 2)
- Вызов функции task с аргументами '(1 2 1 2 1 3) и '(5 3 3 1 2 2)
- Функция проверяет, является ли первый аргумент пустым списком. Это не так, поэтому выполняется следующий шаг.
- Первый элемент первого аргумента (1) присутствует во втором аргументе. Поэтому выполняется рекурсивный вызов функции task с аргументами (cdr s1) и (removef (car s1) s2).
- Рекурсивный вызов функции task с аргументами (cdr s1) и (removef (car s1) s2) возвращает (2 1 2 3).
- Добавляем первый элемент s1 (1) к результату рекурсивного вызова (2 1 2 3). Получаем (1 2 1 2 3).
- Возвращаем результат (1 2 1 2 3). Ответ: (1 2)
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д