Вопрос

Я пытаюсь написать функцию, которая может рассчитать 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

Есть несколько вещей, которые стоит упомянуть в этом примере:

  1. Вы должны узнать о map, reduce, и их варианты и родственники. Эти функции очень важны для LISP и очень полезны для работы в списках. map* функции обычно отображают последовательности с последовательности, и reduce обычно преобразует последовательность в одно значение (однако, вы можете использовать такие формы, как (reduce #'cons '(1 2 3))).

  2. Это хороший пример подхода «снизу вверх» к программированию; Программировав простые функции, такие как sum которые часто полезны, вы облегчаете писать dot-product Сверху. Сейчас gpa Функция - это простая, читаемая функция, построенная поверх двух других. Все это одностроители, и все легко читают для всех, кто обладает базовыми знаниями о CL. Это в отличие от методологии, обычно применяемой к ООП.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top