0

我有一个我无法解决的问题,

用户输入一个列表,即

 (total-cost 
   '((anItem 2 0.01) 
     (item 3 0.10) 
     (anotherItem 4 4.10) 
     (item 5 2.51))) 

我需要把最后的数字加在一起,然后返回结果

我当前的代码在每次添加后返回代码。并且还会引发有关意外类型的错误

(defun total-cost (list)
  (loop with sum = 0
        for x in list
      collect (setf sum (+ sum (last x)))
   )
)

错误:(0.01)' is not of the expected typeNUMBER'

感谢任何帮助谢谢戴尔

4

5 回答 5

10

使用LOOP

CL-USER 19 > (loop for (nil nil number) in '((anItem      2 0.01) 
                                             (item        3 0.10) 
                                             (anotherItem 4 4.10) 
                                             (item        5 2.51))
                   sum number)
6.72

REDUCE是另一种选择:

CL-USER 20 > (reduce '+
                     '((anItem      2 0.01) 
                       (item        3 0.10) 
                       (anotherItem 4 4.10) 
                       (item        5 2.51))
                     :key 'third)
6.72
于 2013-10-28T20:05:31.900 回答
5

Loop 有一个sum用于求和的关键字,因此您不必有明确的变量也不必使用setf

(defun total-cost (list)
  (loop for x in list sum (third x)))

正如克里斯所说,(car (last x))如果您要查找的号码始终是最后一个号码,请使用。(third x)或者,如果始终是第三个,则可以像我的示例中那样使用。

另外,请注意,collect如果您的目标是仅返回总和,则使用是错误的;您的示例(更正)返回

(0.01 0.11 4.21 6.7200003)

而我的返回

6.7200003

请注意,如果您想尽可能避免舍入错误,则需要使用指数标记使它们成为双浮点数,例如:

(total-cost '((anItem 2 0.01D0)
             (item 3 0.10D0) 
             (anotherItem 4 4.10D0) 
             (item 5 2.51D0)))
=> 6.72D0
于 2013-10-28T18:42:32.483 回答
3

last返回列表中的最后一个 cons 单元格,而不是它的值。你需要(car (last x))改用。

于 2013-10-28T18:20:43.197 回答
2

以防万一您希望代码为您提供精确的结果,而不是简短:

(defun kahan-sum (floats)
  (loop
     :with sum := 0.0 :and error := 0.0
     :for float :in floats
     :for epsilon := (- float error)
     :for corrected-sum := (+ sum epsilon) :do
     (setf error (- corrected-sum sum epsilon) sum corrected-sum)
     :finally (return sum)))

(defun naive-sum (floats) (loop :for float :in floats :sum float))

(let ((floats (loop :repeat 1000 :collect (- (random 1000000.0) 1000000.0))))
  (format t "~&naive sum: ~f, kahan sum: ~f" (naive-sum floats) (kahan-sum floats)))
;; naive sum: -498127420.0, kahan sum: -498127600.0

在此处阅读有关它为何如此工作的更多信息:http ://en.wikipedia.org/wiki/Kahan_summation_algorithm

于 2013-10-29T07:17:44.440 回答
0

聚会迟到了... 来点口齿不清而不是looping 怎么样?;-)

(defun sum-3rd (xs)
  (let ((sum 0))
    (dolist (x xs sum) 
      (incf sum (nth 2 x)))))
于 2013-11-20T03:27:57.550 回答