【问题标题】:Replaces occurrences in a list - Racket替换列表中的匹配项 - Racket
【发布时间】:2020-02-26 02:41:42
【问题描述】:

我正在编写一个名为 ptyper 的函数,它接受一个嵌套列表 nl。此函数用 n 替换所有出现的数字,用 s 替换所有出现的符号。这就是我现在拥有的:

(define (ptyper nl) (cond
((null? nl) '())
((list? nl)
 (let ((ls (car nl)))
  (list (ptyper ls))))
((number? (car nl))
 (cons "n" (cdr nl)))
((symbol? (car nl))
 (cons "s" (cdr nl)))
(else
 (cons (car nl) (cdr nl)))))

我运行了这个测试 (ptyper '(2 (abc () "abc"))) 但收到一个错误,表明他们违反了合同。我不确定我做错了什么,所以如果可以使用一些帮助。谢谢!

【问题讨论】:

    标签: recursion scheme racket r5rs


    【解决方案1】:

    这是一个可能的解决方案,只有一个功能:

    (define (ptyper nl)
      (cond
        ((null? nl) '())      ; if the argument is an empty list, return the empty list
        ((list? nl)           ; if the argument is a list, then
         (let* ((c (car nl))  ; get its first element
                (nc (cond ((number? c) "n") ; transform it for numbers
                          ((symbol? c) "s") ; and symbols
                          ((list? c) (ptyper c)) ; if a list recur over it
                          (else c))))       ; otherwise (e.g. a string) return as it is
           (cons nc (ptyper (cdr nl)))))    ; recursive call on the rest of the list
        (else nl)))  ; this should never happen for the specification,
                     ; return the parameter or cause an error
    

    请注意,您的错误是由递归调用引起的。当在原子上调用该函数时,例如2,首先它会检查nulllist?,这些检查返回false。然后它检查(number (car nl)),但nl 等于2,所以car 失败。

    【讨论】:

      【解决方案2】:

      这是 S 表达式的数据定义,它对您的数据进行建模。

      ; An S-expr is one of: 
      ; – Atom
      ; – SL
      
      ; An SL is one of: 
      ; – '()
      ; – (cons S-expr SL)
      
      
      ; An Atom is one of: 
      ; – Number
      ; – String
      ; – Symbol
      

      我们对除Atom 之外的每一种数据都有谓词,所以我们制作atom?

      ;; Any -> Boolean
      ;; is the x an atom?
      (define (atom? x)
        (not (list? x)))
      

      我们按照数据的结构为我们的功能构建“模板”:

      (define (func sexp)
        (cond
          [(atom? sexp) (func-atom sexp)]
          [else (func-sl sexp)]))
      
      
      (define (func-sl sl)
        (cond
          [(empty? sl) ...]
          [else (... (func (first sl)) ... (func-sl (rest sl)) ...)]))
      
      
      (define (func-atom at)
        (cond
          [(number? at) ...]
          [(string? at) ...]
          [(symbol? at) ...]))
      

      我们填补空白:

      ; Atom -> String
      (define (subs-atom at)
          (cond
          [(number? at) "n"]
          [(string? at) at]
          [(symbol? at) "s"]))
      
      
      ; SL -> SL
      (define (subs-sl sl)
        (cond
          [(empty? sl) sl]
          [else (cons (subs-sexp (first sl))
                      (subs-sexp (rest sl)))]))
      
      ; S-exp -> S-exp
      (define (subs-sexp sexp)
        (cond
          [(atom? sexp) (subs-atom sexp)]
          [else (subs-sl sexp)]))
      

      使用ptyper的接口:

      (define (ptyper nl)
        (subs-sexp nl))
      
      (ptyper '(2 (abc () "abc")))
      ; => '("n" ("s" () "abc"))
      

      【讨论】:

        猜你喜欢
        • 2021-03-27
        • 2017-06-03
        • 2021-09-29
        • 2016-11-04
        • 1970-01-01
        • 1970-01-01
        • 2012-03-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多