Лисп L oop Самый большой номер - PullRequest
0 голосов
/ 07 апреля 2020

Я некоторое время возился с программами на Лиспе, и одна вещь, которую я никогда не смогу понять, это как использовать al oop в списке внутри функции. Я пытаюсь создать функцию, которая будет принимать список в качестве параметров при использовании do ... l oop. Я знаю, как это сделать с помощью операторов if, но теперь мне нужно использовать al oop. У кого-нибудь есть подсказки, как это сделать?

(defun maximum (a_list)
  (if (= (length a_list) 1)
      (car a_list)
      (if (> (car a_list) (maximum (cdr a_list)))
          (car a_list)
          (maximum (cdr a_list))))
    (format t "~d" a_list))

Вот что я имею до сих пор в операторах if. Они могут работать неправильно, но, по крайней мере, они работают.

Ответы [ 3 ]

2 голосов
/ 07 апреля 2020

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

Прежде всего, при написании функции следует также проверять специальные случаи, пока вы не проверяете пустой список , Таким образом, структура функции может быть такой:

(defun maximum (l)
  (if (null l)
      nil        ; or give an error
      ...normal solution...))

В случае возврата nil эта структура в Common Lisp идентична следующей, учитывая, что and оценивает свои аргументы в последовательности и возвращает nil, как только аргумент оценивается как nil, в противном случае возвращает значение последнего аргумента:

(defun maximum (l)
  (and l ...normal solution...))

Здесь представлены альтернативные решения.

Без l oop или рекурсия с предопределенными функциями reduce ( ручной ) и max ( ручной ).

(defun maximum (l)
  (and l (reduce #'max l)))

С конструкцией dolist ( manual ), который перебирает переменную по списку:

(defun maximum (l)
  (and l (let ((result (car l)))
           (dolist (x (cdr l) result)
             (when (> x result)
               (setf result x))))))

И, наконец, с компактной версией do ( manual ):

(defun maximum (l)
  (and l (do ((maximum-so-far (car l) (max (pop l) maximum-so-far)))
             ((null l) maximum-so-far))))
1 голос
/ 07 апреля 2020

С loop решение тривиально:

(loop for x in '(1 2 7 4 5) maximize x)

Поэтому я предполагаю, что вы намереваетесь написать функцию с do l oop. В этом случае вам придется пройти по списку, отслеживая максимальный элемент, и обновив это значение, если вы найдете большее значение:

(setq list '(1 2 7 4 5))

(do* ((l list (cdr l)) 
      (x (car l) (car l)) 
      (max x) ) 
     ((null l) max) 
 (if (> x max) 
   (setq max x) ))
0 голосов
/ 08 апреля 2020
(defun maximum (list)
  (let ((result)) ;; short for ((result nil))
    (dolist (x list)
      (if result
          (when (> x result)
            (setf result x))
          (setf result x)))
    result))

(dolist (x list) ... ) похоже на Python [... for x in list]

Типичным императивным стилем является создание переменной с let и setf для изменения ее значения.

...