如何在方案中管理任意列表以添加和计数数字

时间:2015-02-04 04:59:47

标签: scheme

所以我创建了基本功能

(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>

3 个答案:

答案 0 :(得分:1)

这与previous question有关。实质上,您只需要应用标准模板来遍历列表列表,根据问题做适当的事情:

  1. 测试null?列表,基本情况。
  2. 测试当前元素是否为pair?,在这种情况下,我们必须重复carcdr并合并答案。
  3. 否则,我们在原子中。
  4. 此外,对于您提到的函数,我们必须测试另一种情况:如果当前原子是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的机器指令的较低级别的运算符carcdr,而是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)))))