我正在尝试使用以下方案编写代码(函数):
换句话说,结果应如下:
> (mult '(1 2 3))
6
> (mult '(1 2 x 3 4))
24
> (mult '(1 2 z (3 y 4)))
24 (mine gives me 2)
我的代码允许我跳过符号并将所有内容相乘。但是,一旦我在列表中包含一对,它就好像它不是一个数字,因此它就像它不存在一样。这是我的代码:
(define mult
(lambda (x)
(if (null? x)
1
(if(number? (car x))
(* (car x) (mult (cdr x)))
(mult(cdr x))))))
我试图在找到一对时使用追加,但很明显我做错了...任何有关如何将其包含在一对中的值的帮助将非常感激。
即。 '(1 2 y(3 z 4)= 1 * 2 * 3 * 4
答案 0 :(得分:1)
你快到了,只是错过了名单?测试:
(define (mult lst)
(if (null? lst)
1
(let ((ca (car lst)))
(cond
((number? ca) (* ca (mult (cdr lst))))
((list? ca) (* (mult ca) (mult (cdr lst))))
(else (mult (cdr lst)))))))
修改强>
他是一个不等同的版本:
(define (mult lst)
(cond
((null? lst) 1)
((number? (car lst)) (* (car lst) (mult (cdr lst))))
((cons? (car lst)) (* (mult (car lst)) (mult (cdr lst))))
(else (mult (cdr lst)))))
如你所见,(car lst)可能不止一次被评估,所以我在第一个版本中使用let来避免这种情况。
答案 1 :(得分:0)
这是一种稍微先进的技术,但这个问题可以很容易地表达为尾递归算法。
(define (mult lst)
(let multiplying ((lst lst) (r 1)) ; r is the multiplicative identity...
(if (null? lst)
r
(let ((next (car lst))
(rest (cdr lst)))
(multiplying rest (cond ((number? next) (* next r))
((list? next) (* (mult next) r))
(else r)))))))
> (mult '(1 2 3 a b (((((10)))))))
60
使用尾递归有性能影响但是,不可否认,它不是第一个学习的东西 - 递归。但是,在这种情况下,因为列表通常很长,所以避免每个列表元素的堆栈帧可以节省大量成本;使用尾调用避免了堆栈帧。