Добавление двух или более списков на основе их пары в списке
Я не слишком опытен в функциональном стиле и не хочу использовать какие-либо функции набора, поэтому у меня проблема. Я действительно борюсь, должен ли я сделать рекурсивно или по-другому.
У меня есть коллекция пар в списке, например, так:
((4 2) (3 1) (3 2) (2 4) etc...)
В этой паре '(4 2) второй элемент'2'сообщает мне, каким другим парам он соответствует в данном случае'(3 2). Итак, я добавляю эти две пары вместе, используя их первый элемент, в данном случае это "4" и "3". Новая пара сейчас '(7 2). И так далее для других пар в списке тоже. Наконец, он должен вернуть:
((7 2) (3 1) (2 4))
Я бы не заботился о заказе., У меня уже есть рабочая функция, которая добавляет две разные пары. Единственное допущение, связанное с этой функцией, состоит в том, что пары совпадают.
Следовательно, я хочу манипулировать этим списком пар, чтобы получить список такими способами.
Примеры:
take the list ((4 2) (3 1) (3 2) (2 4))
matching-pairs: '(4 2) and '(3 2)
and then return --> ((7 2) (3 1) (2 4))
take the list ((2 1) (3 2) (1 2) (5 1) (6 3))
matching-pairs: '(2 1) and '(5 1)
'(3 2) and '(1 2)
and then return --> ((7 1) (4 2) (6 3))
Спасибо за ваше время и усилия.
2 ответа
Перебирайте свой список и сохраняйте каждую пару car
в список в assoc
это выглядит так:
original: ((2 . 1) (3 . 2) (1 . 2) (5 . 1) (6 . 3))
new: ((1 . (2 5))
(2 . (3 1))
(3 . (6))
Затем суммируем все cdr
s и переверните каждую пару, чтобы получить это:
((7 . 1) (4 . 2) (6 . 3))
(defun get-pairs (alist index)
(cond
(alist
(if (= (nth 1 (car alist)) index)
(append (list (caar alist)) (get-pairs (cdr alist) index))
(get-pairs (cdr alist) index)))
((not alist)
'nil)))
(defun get-iterator (alist)
(labels
((f (alist res)
(cond
(alist
(if (member (nth 1 (car alist)) res)
(f (cdr alist) res)
(f (cdr alist) (append (cdar alist) res))))
((not alist)
res))))
(f alist 'nil)))
(defun get-value (alist)
(loop for i in (get-iterator alist)
collect (get-pairs alist i)))
(defun list-sum (alist)
(loop for i in (get-value alist)
collect (apply #'+ i)))
(defun match-value (alist)
(loop for i in (get-iterator alist)
for j in (list-sum alist)
collect (append (list j) (list i))))
(defparameter *my-list* '((2 1) (3 1) (4 2) (5 2) (8 1) (9 2) (1 3) (0 3)))
(print (match-value *my-list*))
Извините за грязный код, но это должно сработать, если я правильно понял проблему.