如果您有结构和列表列表,如何对列表中的数字进行求和

时间:2014-11-04 23:41:42

标签: scheme racket

;; An ATOM is one of: 
;; -- Symbol
;; -- String 
;; -- Number

;; An SEXP (S-expression) is one of: 
;; -- empty 
;; -- (cons ATOM SEXP)
;; -- (cons SEXP SEXP)

所以我想总结一下SEXP中的所有数字!这是我的代码,

;; sum-numbers: sexp -> Number

(define (sum-numbers sexp)
(cond 
  [(empty? sexp) 0]
  [(ATOM? (first sexp)) (+ (atom-sum-numbers (first sexp))
                           (sum-numbers (rest sexp)))]
  [(SEXP? (first sexp)) (+ (sum-numbers (first sexp))
                           (sum-numbers (rest sexp)))]))

;; atom-sum-numbers: Atom -> Number 
(define (atom-sum-numbers a)
    (cond 
       [(symbol? a) 0]
       [(number? a) (+ (ATOM-number a)
                    (atom-sum-numbers a))]
       [(string? a) 0]))

然而,错误显示cond:所有问题结果都是错误的。我想知道那里发生了什么。

2 个答案:

答案 0 :(得分:1)

您将结构访问器程序与列表操作程序混合在一起,这些程序不会起作用 - 您必须保持一致,如果使用结构,那么您必须使用结构自己的程序。

另外,你的ATOM结构看起来是错误的,它说的是:一个原子由一个符号组成,一个字符串一个数字(三个)事情,而不仅仅是其中之一!)。当然,symbol?number?string?谓词不会对该结构起作用,这就是cond抱怨所有条件的原因是假的。

我建议你尝试别的东西,其中原子真的是原子,而不是结构。否则,您必须重新考虑ATOM结构,其当前形式不会以您想象的方式工作。例如,这将起作用:

(define (sum-numbers sexp)
  (cond 
    [(empty? sexp) 0]
    [(SEXP? (SEXP-ATOM sexp)) (+ (sum-numbers (SEXP-ATOM sexp))
                                 (sum-numbers (SEXP-SEXP sexp)))]
    [else (+ (atom-sum-numbers (SEXP-ATOM sexp))
             (sum-numbers (SEXP-SEXP sexp)))]))

(define (atom-sum-numbers a)
  (cond 
    [(symbol? a) 0]
    [(number? a) a]
    [(string? a) 0]))

让我们对它进行测试,并注意原子如何是普通的原子,而不是ATOM结构的实例:

(sum-numbers 
 (make-SEXP 'x 
            (make-SEXP 7
                       (make-SEXP "a" 
                                  '()))))
=> 7

答案 1 :(得分:0)

 ;; atom? : Any -> Boolean 
 ;; true if input is an Atom false otherwise 
 (define (atom? at) 
   (or (number? at)
       (symbol? at)
       (string? at)))

 ;; sexp? : Any -> Boolean 
 ;; true if input is n Sexp, false otherwise 
 (define (sexp? s) 
   (or
     (empty? s)
     (and (cons? s) 
          (atom? (first s))
          (sexp? (rest s)))
     (and (cons? s)
          (sexp? (first s))
          (sexp? (rest s)))))

 ;; sum-numbers: sexp -> Number
 ;; given a sexp returns the sum of all the Numbers in the list

 ;; sum-numbers: Sexp -> Number
 (define (sum-numbers sexp)
   (cond 
     [(empty? sexp) 0]
     [(atom? (first sexp)) (+ (atom-sum-numbers (first sexp))
                              (sum-numbers (rest sexp)))]
     [(sexp? (first sexp)) (+ (sum-numbers (first sexp))
                              (sum-numbers (rest sexp)))]))


 ;; atom-sum-numbers: anything(symbol number or string) -> Number
 ;; if the given is a number, add it 

 (define (atom-sum-numbers a)
   (cond 
     [(symbol? a) 0]
     [(number? a) a]
     [(string? a) 0]))