所以我创建了基本功能
(define (countNumbers lst)
(cond
((null? lst) 0)
((number? (car lst))(+ 1 (countNumbers (cdr lst))))
(else (countNumbers (cdr lst)))))
(define (sumNumbers lst)
(cond
((null? lst) 0)
((number? (car lst))(+ (car lst) (sumNumbers (cdr lst))))
(else (sumNumbers (cdr lst)))))
现在有一种方法,你如何使这些函数适用于任意列表,就像我传入(1(2(3)))到countNumbers它返回3并且如果我将它传递给sumNumbers它返回6?< / p>
答案 0 :(得分:1)
这与previous question有关。实质上,您只需要应用标准模板来遍历列表列表,根据问题做适当的事情:
null?
列表,基本情况。pair?
,在这种情况下,我们必须重复car
和cdr
并合并答案。此外,对于您提到的函数,我们必须测试另一种情况:如果当前原子是number?
;这里组合的方式是添加结果。例如:
(define (countNumbers lst)
(cond ((null? lst) 0)
((pair? lst)
(+ (countNumbers (car lst))
(countNumbers (cdr lst))))
((number? lst) 1)
(else 0)))
(define (sumNumbers lst)
(cond ((null? lst) 0)
((pair? lst)
(+ (sumNumbers (car lst))
(sumNumbers (cdr lst))))
((number? lst) lst)
(else 0)))
按预期工作:
(countNumbers '(1 x (x 2) x (3 (4 x (5) 6) 7)))
=> 7
(sumNumbers '(1 x (x 2) x (3 (4 x (5) 6) 7)))
=> 28
答案 1 :(得分:1)
不是使用源自IBM 704的机器指令的较低级别的运算符car
和cdr
,而是countNumbers
可以使用{在更高的抽象级别实现(define (countNumbers lox)
(length (filter number? (flatten lox))))
。 {3}}和function composition,如sequences as conventional interfaces:
flatten
(define (flatten x)
(cond ((null? x) '())
((not (pair? x)) (list x))
(else (append (flatten (car x))
(flatten (cdr x))))))
是一种常见的列表操作。但它不包括在方案标准中。
来自The Structure and Interpretation of Computer Programs:
#lang racket
内置flatten
的{{1}}的{{3}}基于迭代和cons
提供了更快的实施:
(define (flatten orig-sexp)
(let loop ([sexp orig-sexp] [acc null])
(cond [(null? sexp) acc]
[(pair? sexp) (loop (car sexp) (loop (cdr sexp) acc))]
[else (cons sexp acc)])))
在R5RS计划中,这将是:
(define (flatten orig-sexp)
(letrec
((loop (lambda (sexp acc)
(cond ((null? sexp) acc)
((pair? sexp)
(loop (car sexp)
(loop (cdr sexp) acc)))
(else (cons sexp acc))))))
(loop orig-sexp '())))
答案 2 :(得分:0)
您可以添加第二级递归,如下所示:
(define (countNumbers lst)
(cond
((null? lst) 0)
((number? (car lst))(+ 1 (countNumbers (cdr lst))))
((list? (car lst)) (+ (countNumbers (car lst)) (countNumbers (cdr lst))))
(else (countNumbers (cdr lst)))))
(define (sumNumbers lst)
(cond
((null? lst) 0)
((number? (car lst))(+ (car lst) (sumNumbers (cdr lst))))
((list? (car lst)) (+ (sumNumbers (car lst)) (sumNumbers (cdr lst))))
(else (sumNumbers (cdr lst)))))