从列表中添加数字(例如asdf125dkf将返回8)

时间:2010-11-04 01:33:40

标签: functional-programming lisp scheme

我需要一个函数,它将接收一个字符和数字列表,然后返回加起来的数字(忽略字符)。这就是我到目前为止所做的:

(define (adder lst)
   (cond
     ((null? lst)
       0)
     ((number? (car lst))
      (+(adder (car lst)) (adder (cdr lst))))
     ((char? (car lst))
      ((adder(cdr lst))))
     ))

(display (adder '(asd12sdf)))

在codepad.org上运行它只显示无效。我知道代码是错误的,因为它看起来不对,但我不知道如何解决它...我如何让函数跟踪它找到的第一个数字并将其添加到它找到的下一个数字,同时跳过所有字符?

3 个答案:

答案 0 :(得分:3)

在您的第二个cond案例中,没有理由在adder上运行(car lst)。只需将(car list)本身添加到递归步骤即可。

对于最后一行,请勿测试(char? (car lst))。只需将最后一行设为else子句,这意味着任何数字都会转到else行。

你失败的原因是因为你的输入不满足cond条件的任何,而你没有else,所以答案是什么都没有(即(void))。

最后一个错误在于您提供的输入。 '(asd12sdf)字面上是一个名为“asd12sdf”的一个符号的列表。我想你想给它'(a s d 1 2 s d f)(一个包含6个符号和2个数字的列表)应该得到3.注意符号'a和字符{{1}之间有一个非常重要的区别}。

看起来你有逻辑,所以你的问题似乎不是函数式语言,只是Scheme的语法。

编辑,在最后一行中,您有#\a,其中包含太多的parens。这将导致Scheme尝试将加法器的结果(这是一个数字)作为一个过程进行评估(错误!)。

答案 1 :(得分:0)

您应该观察到此函数或多或少sum,只需使用fold即可定义。

(define (adder lst)
   (fold + 0 lst))

折叠做什么?基本上,它的定义如下:

(define (fold f initial lst)
  (if (null? lst)
     initial
     (fold f (f (car lst) initial) (cdr lst))))

(换句话说,它在lst的每个元素上调用f,一个2个参数的函数,使用lst的汽车作为第一个参数,累积的结果作为f的第二个参数。)

这里需要解决的问题是+不知道如何操作非数字值。没问题,你已经处理过了。如果它是一个角色会发生什么?好吧,你没有在总值中添加任何内容,所以将其替换为0.因此,您的解决方案就像:

(define (adder lst)
   (fold your-new-protected-+ 0 lst))

答案 2 :(得分:0)

在Common Lisp中:

(reduce #'+ '(1 #\a #\b 2 1 2 #\c #\d 4)
        :key (lambda (item) (if (numberp item) item 0)))

(loop for item in '(1 #\a #\b 2 1 2 #\c #\d 4)
      when (numberp item) sum item)