Добавление двух или более списков на основе их пары в списке

Я не слишком опытен в функциональном стиле и не хочу использовать какие-либо функции набора, поэтому у меня проблема. Я действительно борюсь, должен ли я сделать рекурсивно или по-другому.

У меня есть коллекция пар в списке, например, так:

((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))

Затем суммируем все cdrs и переверните каждую пару, чтобы получить это:

          ((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*))

Извините за грязный код, но это должно сработать, если я правильно понял проблему.

Другие вопросы по тегам