2014-11-04 61 views
0
;; 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:所有問題的結果都是假的。我想知道那裏發生了什麼。

+0

看看[文檔](http://docs.racket-lang.org/reference/define-struct.html)。當你寫'(define-struct ATOM(symbol string number))'時,你說'ATOM'是三個元素的組合:一個符號,一個字符串和一個數字 - 不只是其中的一個! – 2014-11-05 01:18:42

+1

@ÓscarLópezOP似乎想要的東西類似於C的工會。我不知道是否有計劃實施支持工會,這似乎記憶不安全。當然,靜態類型語言具有代數數據類型的概念,但是這不適用於Scheme。 – 2014-11-05 04:15:55

回答

1

您正在將struct accessor過程與列表操作過程混合在一起,這不起作用 - 您必須保持一致,如果使用了結構,那麼您必須使用結構自己的過程。

此外,您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

謝謝!我想知道ATOM是否應該是一個結構。在這種情況下,ATOM是平坦的。所以我想在這種情況下,我們需要寫ATOM?函數確定它是否是ATOM和SEXP?無論是SEXP。 – ads27 2014-11-05 18:08:05

+0

另外,SEXP應該是一個不是結構的列表。 – ads27 2014-11-05 22:07:25

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]))