Программа на Лиспе, которая дублирует элемент списка, используя список целых чисел - PullRequest
0 голосов
/ 27 сентября 2018

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

(A B C D)

, дублирующийся на:

(1 5 4 2)

Я бы имел

(A B B B B B C C C C D D)

Пока у меня есть

(defun COPY (X Y) 
  (if (zerop Y) 
      nil 
      (cons S (COPY X (1 - Y)))))

Конечно, это только дублирование одного элемента несколько раз.У кого-нибудь есть хорошая идея, как это сделать?

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Используйте mapcan и make-list (что является библиотечной версией вашего copy):

(mapcan (lambda (letter num)
          (make-list num :initial-element letter))
        '(A B C D) '(1 5 4 2))
==> (A B B B B B C C C C D D)

или просто

(mapcan #'copy '(A B C D) '(1 5 4 2))

Если вам необходимо использовать простую рекурсию, вы также можете написать

(defun copy-list-elements (elements counts)
  (and elements counts
       (let ((count (pop counts)))
         (if (plusp count)
             (cons (car elements)
                   (copy-list-elements elements
                                       (cons (1- count) counts)))
             (copy-list-elements (cdr elements)
                                 counts)))))
(copy-list-elements '(A B C D E) '(1 5 4 0 2))
==> (A B B B B B C C C C E E)

Обратите внимание, что рекурсивная версия длиннее и, вероятно, медленнее.

0 голосов
/ 28 сентября 2018

Зациклите два списка, позвоните copy и добавьте результаты.

(loop for letter in letters
      for count in counts
      nconcing (copy letter count))
...