Ignore non-number values in a list and find the sum recursive method

丶灬走出姿态 提交于 2019-12-12 02:55:18

问题


I need to create a recursive method in LISP that takes the numbers in a list and finds the sum. Anything in the list that is not a number is skipped (For example, if the list contains "Cheese 12 Dog 8 Shoe 5", the output would be 25).

Right now my code finds the sum, but throws an error if there is anything in the list that is not a number. What can be changed to fix that?

(defun adder (lis)
   (cond
    ((null lis) 0)
    (t (eval (cons '+ lis)) )
  )
)

回答1:


This would do:

(defun adder (lis)
  (if (null lis)
    0
    (let ((c (car lis)))
      (if (numberp c)
        (+ c (adder (cdr lis)))
        (adder (cdr lis))))))

Your version is not recursive (you don't call adder inside of adder), maybe you meant something like this (which is non-recursive)?

(defun adder (lis)
  (apply '+ (remove-if-not 'numberp lis)))



回答2:


Using apply on lists that can be long is a bit dangerous. If the list is longer than call-arguments-limit, then (apply '+ list) won't work. Now, call-arguments-limit is typically pretty big in modern Lisps, but it's allowed to be as small as 50. For more information about this, see:

  • Common lisp: How many argument can a function take? (this answer uses (reduce '+ …))
  • In Lisp, how many inputs can the + function actually have?

I think your best bet would be to use reduce '+ list with a key function that takes each number to itself and each non-number to 0. (This key function is what abiessu mentioned in a comment.)

(reduce '+ list :key (lambda (x) (if (numberp x) x 0)))
CL-USER> (let ((list '(cheese 12 dog 8 shoe 5)))
           (reduce '+ list :key (lambda (x) (if (numberp x) x 0))))
25
CL-USER> (let ((list '()))
           (reduce '+ list :key (lambda (x) (if (numberp x) x 0))))
0

Instead of using a more complex key function, you could also use (remove-if-not 'numberp list) to get rid of the non-numbers (or (remove-if (complement 'numberp) list)):

CL-USER> (let ((list '(cheese 12 dog 8 shoe 5)))
           (reduce '+ (remove-if-not 'numberp list)))
25
CL-USER> (let ((list '()))
           (reduce '+ (remove-if-not 'numberp list)))
0


来源:https://stackoverflow.com/questions/19936840/ignore-non-number-values-in-a-list-and-find-the-sum-recursive-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!