Проблемы с NTH в общем LISP
-
28-10-2019 - |
Вопрос
Я пытаюсь написать функцию, которая может рассчитать GPA. Теперь я могу сделать ограниченный расчет (только 3), но я застрял в том, как расчета больше, без использования цикла или рекурсии (это требование субъекта), как потратить NTH функцию? Например: (nth n), если да, то это значит, мне нужно написать выражение Lambda? Как новичок, я ясно описываю этот вопрос, действительно нуждается в некоторой помощи.
Блеск это точки оценки Прилив это кредитные часы.
Gpa = (GradePoint *credithour + GradePoint *credithour) / (Сумма Credithour) как: (3*1+3*2+4*1)/(1+2+1)
Вот мой код:
(defun gpa (Glist Clist)
(format t "~3,2f~%"
(/
(+(nth 0 (mapcar #' * Glist Clist))
(nth 1 (mapcar #' * Glist Clist))
(nth 2 (mapcar #' * Glist Clist)))
(+ (nth 0 Clist)
(nth 1 Clist)
(nth 2 Clist))
);end "/"
);end "format"
(values) );end
Решение
Если вы используете nth
Чтобы пройти список, вы делаете это неправильно. В этом случае вы можете написать функцию суммирования:
(defun sum (items)
(reduce #'+ items))
Другие советы
РЕДАКТИРОВАТЬ
Это кажется хорошей возможностью, чтобы подчеркнуть некоторые общие (маленькие C) и идеи LISP, поэтому я выяснил свой ответ, чтобы проиллюстрировать.
Как упомянуто в другом ответе, вы можете использовать sum
функция, которая работает в списках (чисел):
(defun sum (nums)
(reduce #'+ nums))
Продукт DOT представляет собой мультипликативную сумму двух (равных) векторов:
(defun dot-product (x y)
(sum (mapcar #'* x y)))
Функция gpa
это простое сочетание двух:
(defun gpa (grades credits)
(/ (dot-product grades credits) (sum credits)))
Пример из вопроса приводит к ответу, который мы ожидаем (минус форматирован как поплавок):
(gpa '(3 3 4) '(1 2 1))
> 13/4
Есть несколько вещей, которые стоит упомянуть в этом примере:
Вы должны узнать о
map
,reduce
, и их варианты и родственники. Эти функции очень важны для LISP и очень полезны для работы в списках.map*
функции обычно отображают последовательности с последовательности, иreduce
обычно преобразует последовательность в одно значение (однако, вы можете использовать такие формы, как(reduce #'cons '(1 2 3))
).Это хороший пример подхода «снизу вверх» к программированию; Программировав простые функции, такие как
sum
которые часто полезны, вы облегчаете писатьdot-product
Сверху. Сейчасgpa
Функция - это простая, читаемая функция, построенная поверх двух других. Все это одностроители, и все легко читают для всех, кто обладает базовыми знаниями о CL. Это в отличие от методологии, обычно применяемой к ООП.Там нет повторения кода. Конечно,
sum
используется более одного раза, но только там, где это имеет смысл. Вы можете сделать очень немного больше, чтобы абстрагировать понятие суммы элементов списка. В схеме более естественно писать функции с функциями, и это совершенно другая тема. Это простой пример, но никакие две функции не делают то же самое.