Common Lisp 中 Nth 的问题

发布于 2024-12-03 10:52:10 字数 711 浏览 1 评论 0原文

我正在尝试编写一个可以计算 GPA 的函数。现在我可以进行有限的计算(只有3个),但我坚持如何计算更多,而不使用循环或递归(这是主题的要求)如何消耗第n个函数?比如: (nth n) ,如果是这样,这是否意味着我需要编写一个 lambda 表达式?作为一个新手,我可能无法清楚地描述问题,确实需要一些帮助。

Glist 是成绩点 Clist 是学时。

GPA=( 学分 * 学分 + 学分 * 学分) / (学分之和),例如:(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 

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 Clist))
          (nth 2 (mapcar #' * Glist Clist)))
        (+ (nth 0 Clist)
           (nth 1 Clist)
           (nth 2 Clist))
                   );end "/"
                   );end "format" 
       (values)    );end 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

全部不再 2024-12-10 10:52:10

编辑

这似乎是一个很好的机会来强调一些常见的(小c)Lisp 想法,所以我充实了我的答案来说明。


正如另一个答案中提到的,您可以使用对(数字)列表进行操作的 sum 函数:

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

点积是两个(等长)向量的乘法和:

(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. 您应该了解<一href="http://www.lispworks.com/documentation/HyperSpec/Body/f_map.htm" rel="nofollow">地图reduce 及其变体和亲属。这些函数对于 Lisp 来说非常重要,对于列表操作非常有用。 map* 函数通常将序列映射到序列,而 reduce 通常将序列转换为单个值(但是,您可以使用类似 (reduce #'cons '(1 2 3)))。

  2. 这是“自下而上”编程方法的一个很好的例子;通过编写通常有用的简单函数(例如 sum),您可以轻松地在其上编写 dot-product。现在,gpa 函数是一个构建在其他两个函数之上的简单、可读的函数。这些都是简短的文字,对于任何具有 CL 基础知识的人来说都可以轻松阅读。这与通常应用于 OOP 的方法形成对比。

  3. 没有重复的代码。当然,sum 会被多次使用,但仅限于有意义的地方。您可以做很少的事情来抽象列表元素之和的概念。在Scheme中用函数来编写函数更为自然,这是一个完全不同的话题。这是一个简单的示例,但没有两个函数执行相同的操作。

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.

凉风有信 2024-12-10 10:52:10

如果您使用 nth 来遍历列表,那么您就错了。在这种情况下,您可能需要编写一个求和函数:

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

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))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文