Программа, возвращающую список вида: первый элемент — атом, появляющийся в списке один раз, второй - два раза и т.д - Lisp
Формулировка задачи:
Помогите пожалуйста!!
Есть список атомов. Написать программу, возвращающую список вида:
первый элемент — атом исходного списка, появляющийся в списке один раз (с
учетом вхождений в подсписки), второй элемент — атом, появляющийся два
раза (с учетом вхождений в подсписки) и т.д. Если есть несколько атомов,
появляющихся одинаковое количество раз, то их объединить в список.
Решение задачи: «Программа, возвращающую список вида: первый элемент — атом, появляющийся в списке один раз, второй - два раза и т.д»
textual
Листинг программы
(defun flatten (w) (if (atom w) `(,w) (mapcan #'flatten w))) (defun sort-count (w &aux (v (flatten w))) (sort (loop for a in (remove-duplicates v) collect `(,a ,(count a v))) #'< :key #'cadr)) (defun glue (w &optional (b (cadar w)) ac) (cond ((null w) ac) ((equal b (cadadr w)) (glue (cdr w) b (cons (caar w) ac))) ((cons (if ac (reverse (cons (caar w) ac)) (caar w)) (glue (cdr w) (caddar w) nil))))) (defun glue-sort-count-deep (w) (glue (sort-count w))) > (glue-sort-count-deep '(a b c (a ((b c) c) c) c)) ((A B) C) > (glue-sort-count-deep '(z b c (a ((b c) c) c) c)) ((Z A) B C)
Объяснение кода листинга программы
- Написана функция
flatten
, которая принимает в качестве аргумента списокw
и возвращает список, состоящий из атомов спискаw
. - Если список
w
является атомом, то возвращается список, содержащий этот атом. - В противном случае, с помощью функции
mapcan
вызывается рекурсивно функцияflatten
для каждого элемента спискаw
. - Написана функция
sort-count
, которая принимает в качестве аргументов списокw
и вспомогательную переменнуюv
. - В функции
sort-count
с помощью циклаloop
удаляются дубликаты из спискаv
. - Затем с помощью функции
collect
создается новый список, содержащий пары: первый элемент — атом из спискаv
, второй элемент — количество появлений этого атома в спискеv
. - Созданный список сортируется с помощью функции
sort
в порядке возрастания. - Вспомогательная переменная
v
передается в функциюglue
. - Написана функция
glue
, которая принимает в качестве аргументов списокw
, вспомогательную переменнуюb
и списокac
. - Если список
w
пуст, то возвращается списокac
. - Если значение
b
равно (cadadr w), то вызывается рекурсивно функцияglue
для спискаcdr w
, значенияb
и спискаac
. - В противном случае, с помощью условного выражения
cond
проверяется, является ли первый элемент спискаw
атомом. - Если это так, то вызывается рекурсивно функция
glue
для спискаcdr w
, значенияb
и спискаac
. - В противном случае, создается новый список, содержащий все элементы списка
w
, кроме первого. - Этот новый список передается в функцию
glue
вместе со значениемb
и спискомac
. - Написана функция
glue-sort-count-deep
, которая принимает в качестве аргумента списокw
и возвращает список, отсортированный по количеству появлений каждого атома в спискеw
. - Вызывается функция
glue-sort-count-deep
с аргументом'(a b c (a ((b c) c) c) c'
, который возвращает(A B) C
. - Вызывается функция
glue-sort-count-deep
с аргументом'(z b c (a ((b c) c) c) c'
, который возвращает(Z A) B C
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д