Сконструировать функцию которая реализовывает декартово произведение множеств представленных в форме списков - Lisp
Формулировка задачи:
Сконструировать функцию которая реализовывает декартово произведение множеств представленных в форме списков.
Например для множеств X=(A B C) и Y=(2 3) результатом вызова (CARTEZIAN X Y)
будет список ((A 2) (A 3) (B 2) (B 3) (C 2) (C 3) ).
Решение задачи: «Сконструировать функцию которая реализовывает декартово произведение множеств представленных в форме списков»
textual
Листинг программы
(defun decart (s1 s2) (let ((r nil)) (iter (for a in s1) (iter (for b in s2) (collecting (list a b) into r))) r)) ==> DECART (decart '(a b c) '(1 2 3)) ==> ((A 1) (A 2) (A 3) (B 1) (B 2) (B 3) (C 1) (C 2) (C 3)) (defun decart (s1 s2) (apply 'append (mapcar (lambda (x) (mapcar (lambda (y) (list x y)) s1)) s2))) ==> DECART (decart '(a b c) '(1 2 3)) ==> ((1 A) (1 B) (1 C) (2 A) (2 B) (2 C) (3 A) (3 B) (3 C)) (defun decart (s1 s2) (labels ((f (x lst) (cond ((null lst) nil) (t (cons (list x (car lst)) (f x (cdr lst))))))) (cond ((null s1) nil) (t (append (f (car s1) s2) (decart (cdr s1) s2)))))) ==> DECART (decart '(a b c) '(1 2 3)) ==> ((A 1) (A 2) (A 3) (B 1) (B 2) (B 3) (C 1) (C 2) (C 3))
Объяснение кода листинга программы
Вот что происходит в этом коде:
- Функция
decartпринимает два аргумента,s1иs2, которые являются списками. - В первой реализации функция использует два вложенных цикла
iterдля перебора элементовs1иs2. Для каждой пары элементовaизs1иbизs2создается новый элементlist a bи добавляется в результатr. - Во второй реализации функция использует функцию
mapcarдля создания списка функций, каждая из которых принимает элементxизs1и создает новый элементlist x y, гдеy- это каждый элемент изs2. Затем функцияapplyприменяется кappend, чтобы объединить все эти списки в один результат. - В третьей реализации функция использует рекурсивную функцию
f, которая принимает элементxи списокlst. Еслиlstявляетсяnil, функция возвращаетnil. В противном случае она создает новый элементlist x (car lst)и применяетfк оставшейся части спискаcdr lst. В функцииdecartиспользуется условиеcond, чтобы проверить, является лиs1илиs2nil. Если это так, функция возвращаетnil. В противном случае она применяетappendк результатуfи рекурсивно вызываетdecartдля оставшейся части спискаcdr s1иs2.