Написать функцию разности множеств - 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)
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д