开发者

Problems with Nth in common lisp

开发者 https://www.devze.com 2023-04-03 21:10 出处:网络
I\'m trying to write a function that can calculate GPA. Now I can do limited calculation(only 3 ),but I stuck on how to calculate more , without using loop or recursion (that\'s the requirement of sub

I'm trying to write a function that can calculate GPA. Now I can do limited calculation(only 3 ),but I stuck on how to calculate more , without using loop or recursion (that's the requirement of subject) how to expend nth function? like: (nth n) ,if so ,is that mean i need to write a lambda expression? As an newbie, I maynot describe the question clearly, really need some help..

Glist is grade points Clist is credit hours.

GPA=( gradepoint *credithour + gradepoint *credithour) / ( the sum of credithour) like: (3*1+3*2+4*1)/(1+2+1)

here is my code:

(defun gpa (Glist Clist)
     (format t "~3,2f~%" 
      (/ 
        (+(nth 0 (mapcar #' * Glist Clist))
          (nth 1 (mapcar #' * Glist Cl开发者_如何学JAVAist))
          (nth 2 (mapcar #' * Glist Clist)))
        (+ (nth 0 Clist)
           (nth 1 Clist)
           (nth 2 Clist))
                   );end "/"
                   );end "format" 
       (values)    );end 


EDIT

This seems like a good opportunity to emphasize some common (little c) Lisp ideas, so I fleshed out my answer to illustrate.


As mentioned in another answer, you could use a sum function that operates on lists (of numbers):

(defun sum (nums)
  (reduce #'+ nums))

The dot product is the multiplicative sum of two (equal-length) vectors:

(defun dot-product (x y)
  (sum (mapcar #'* x y)))

The function gpa is a simple combination of the two:

(defun gpa (grades credits)
  (/ (dot-product grades credits) (sum credits)))

The example from the question results in the answer we expect (minus being formatted as a float):

(gpa '(3 3 4) '(1 2 1))
> 13/4

There are a few things worth mentioning from this example:

  1. You should learn about map, reduce, and their variants and relatives. These functions are very important to Lisp and are very useful for operating on lists. map* functions generally map sequences to a sequence, and reduce usually transforms a sequence into to a single value (you can however use forms like (reduce #'cons '(1 2 3))).

  2. This is a good example of the "bottom-up" approach to programming; by programming simple functions like sum that are often useful, you make it easy to write dot-product on top of it. Now the gpa function is a simple, readable function built on top of the other two. These are all one-liners, and all are easily readable to anyone who has a basic knowledge of CL. This is in contrast to the methodology usually applied to OOP.

  3. There is no repetition of code. Sure, sum is used more than once, but only where it makes sense. You can do very little more to abstract the notion of a sum of the elements of a list. It's more natural in Scheme to write functions with functions, and that's a whole different topic. This is a simple example, but no two functions are doing the same thing.


If you're using nth to traverse a list, you're doing it wrong. In this case, you might want to write a summing function:

(defun sum (items)
  (reduce #'+ items))
0

精彩评论

暂无评论...
验证码 换一张
取 消