Определить число повторений каждого элемента списка - Lisp
Формулировка задачи:
(defun counter (a L)
(cond
((null L) 0)
((equal a (car L)) (+ 1 (counter a (cdr L))))
(t (counter a (cdr L)))))
(defun f(lst)
(cond ((null lst) nil)
(t (list (car lst) (counter (car lst) lst) (f (remove (car lst) lst))))
)
)
(f '(1 2 3 4 4 4 1 2 1))Решение задачи: «Определить число повторений каждого элемента списка»
(defun cnt (lst &optional acc) (cond ((null lst) acc) (T (cnt (cdr lst) ((lambda (a) (if a (subst (cons (car a) (1+ (cdr a))) a acc) (cons (cons (car lst) 1) acc))) (assoc (car lst) acc))))))
Объяснение кода листинга программы
В данном коде определен анонимный функтор (lambda), который принимает в качестве аргумента a некоторый элемент списка lst и текущее значение счетчика повторений этого элемента acc. Если элемент встречается в списке не впервые (т.е. a не равно nil), то он заменяет текущее значение acc на новое значение, равное сумме (1+ (cdr a)) (т.е. увеличивается на единицу), а также добавляет в начало нового значения (cons (car a) (1+ (cdr a))) элемент списка, с которым встретился (car lst). Если элемент встречается впервые, то просто добавляется в начало значения acc, которое затем будет использоваться для подсчета повторений. (defun cnt (lst &optional acc) (cond ((null lst) acc) (T (cnt (cdr lst) ((lambda (a) (if a (subst (cons (car a) (1+ (cdr a))) a acc) (cons (cons (car lst) 1) acc))) (assoc (car lst) acc))))))