我是新手,我对语言不太了解。有人可以向我解释一下这个功能是做什么的吗?
第一个功能:
(define (x l)
(cond
((null? l) 0)
((list? (car l))
(+ (x (car l)) (x (cdr l))))
(else (+ 1 (x (cdr l))))
))
第二功能:
(define (x l)
(cond
((null? l) 0)
((list? (car l))
(+ (x (car l)) (x (cdr l))))
(else (+ (car l) (x (cdr l)))
))
我确实理解了开始,但我理解的条件并不理解。有什么帮助吗?
答案 0 :(得分:1)
我将调用您的第二个函数y
。
以伪代码编写,
x [] -> 0
x [a . b] -> x a + x b , if list a
x [a . b] -> 1 + x b , else, i.e. if not (list a)
y [] -> 0
y [a . b] -> y a + y b , if list a
y [a . b] -> a + y b , else, i.e. if not (list a)
例如,
x [2,3] = x [2 . [3]]
= 1 + x [3]
= 1 + x [3 . []]
= 1 + (1 + x [])
= 1 + (1 + 0 )
和
y [2,3] = y [2 . [3]]
= 2 + y [3]
= 2 + y [3 . []]
= 2 + ( 3 + y [])
= 2 + ( 3 + 0 )
请参阅?第一个计算参数列表中的某些,第二个将它们相加。
当然,可以使用一些非列表来调用这两个函数,但是这两个函数只会导致在第二个子句(car l)
中尝试获取(list? (car l))
时出错。
答案 1 :(得分:1)
您可能已经注意到两者几乎完全相同。它们都在树上积累(折叠)。它们都将在空树上评估为0,并且当汽车为car
时,它们将对cdr
和list?
上的相同过程的结果求和。当car
不是列表时,两者不同,在第一个中,它为另一个元素中的每个元素添加1,它在添加中使用元素本身。可以像这样写一些更紧凑的东西:
(define (sum l)
(cond
((null? l) 0) ; null-value
((not (pair? l)) l) ; term
(else (+ (sum (car l)) (sum (cdr l)))))) ; combine
这是一个概括:
(define (accumulate-tree tree term combiner null-value)
(let rec ((tree tree))
(cond ((null? tree) null-value)
((not (pair? tree)) (term tree))
(else (combiner (rec (car tree))
(rec (cdr tree)))))))
您可以根据accumulate-tree
:
(define (count tree)
(accumulate-tree tree (lambda (x) 1) + 0))
(define (sum tree)
(accumulate-tree tree (lambda (x) x) + 0))
当然,你可以使用accumulate-tree
做更多的事情。它不必变成原子价值。
(define (double tree)
(accumulate-tree tree (lambda (x) (* 2 x)) cons '()))
(double '(1 2 ((3 4) 2 3) 4 5)) ; ==> (2 4 ((6 8) 4 6) 8 10)