Программа, возвращающую список вида: первый элемент — атом, появляющийся в списке один раз, второй - два раза и т.д - 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)

Объяснение кода листинга программы

  1. Написана функция flatten, которая принимает в качестве аргумента список w и возвращает список, состоящий из атомов списка w.
  2. Если список w является атомом, то возвращается список, содержащий этот атом.
  3. В противном случае, с помощью функции mapcan вызывается рекурсивно функция flatten для каждого элемента списка w.
  4. Написана функция sort-count, которая принимает в качестве аргументов список w и вспомогательную переменную v.
  5. В функции sort-count с помощью цикла loop удаляются дубликаты из списка v.
  6. Затем с помощью функции collect создается новый список, содержащий пары: первый элемент — атом из списка v, второй элемент — количество появлений этого атома в списке v.
  7. Созданный список сортируется с помощью функции sort в порядке возрастания.
  8. Вспомогательная переменная v передается в функцию glue.
  9. Написана функция glue, которая принимает в качестве аргументов список w, вспомогательную переменную b и список ac.
  10. Если список w пуст, то возвращается список ac.
  11. Если значение b равно (cadadr w), то вызывается рекурсивно функция glue для списка cdr w, значения b и списка ac.
  12. В противном случае, с помощью условного выражения cond проверяется, является ли первый элемент списка w атомом.
  13. Если это так, то вызывается рекурсивно функция glue для списка cdr w, значения b и списка ac.
  14. В противном случае, создается новый список, содержащий все элементы списка w, кроме первого.
  15. Этот новый список передается в функцию glue вместе со значением b и списком ac.
  16. Написана функция glue-sort-count-deep, которая принимает в качестве аргумента список w и возвращает список, отсортированный по количеству появлений каждого атома в списке w.
  17. Вызывается функция glue-sort-count-deep с аргументом '(a b c (a ((b c) c) c) c', который возвращает (A B) C.
  18. Вызывается функция glue-sort-count-deep с аргументом '(z b c (a ((b c) c) c) c', который возвращает (Z A) B C.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 3.857 из 5
Похожие ответы