这个解决方案是否至少在正确的方向上使用 cond 以获得正确的解决方案(球拍)? (语法问题):

问题描述 投票:0回答:1

Racket中的考试练习就是这个,问题在评论里: ;考虑符号列表 L。我们想检查 L 中是否有 匹配“a”和“b”符号或“1”和“2”符号,其中“a” ;和“1”具有开括号作用,而“b”和“2”分别代表闭括号(即戴克语言);其他 ;符号被忽略。定义一个纯尾递归函数 check-this 返回匹配对的数量,如果匹配则返回 #f ;不遵守括号结构。

;E.g.
;(check-this '(a b a b)) is 2
;(check-this '(h e l l o)) is 0
;(check-this '(6 h a b a 1 h h i 2 b z)) is 3

;(check-this '(6 h a b a 1 h h i b z 2)) is #f (wrong structure)
    #lang racket
    
    
    
    
   (define (check-this L)

;define parametric tail-recursive function
;- x,y : parameters to match
;- z : balance
;- w : oldbalance
;- res : accumulated result  
  
(define (count-xy x y z w res L)


;wrong structure ex. ba   
((if (< z 0) 
      #f));end with error
  
(if (null? L) ;end of list
    ((if (= z 0);all matched parenthesis 
          res ;end fine
          #f));end with errors
)

;remember previous balance in w
(set! w z)
  
;parametrized cases:
;cond works by searching through its arguments in order. It finds the first argument whose first element returns #t when evaluated, 
;and then evaluates and returns the second element of that argument. It does not go on to evaluate the rest of its arguments.
;Make sure that the last argument to every cond statement will always accept anything. This is important for avoiding infinite loops.
  (cond         
                 
                 ;check structure: ab aabbb bbaa
                 ( (eq? (car L) x)  (set! z (+ z 1)) ) ;check a and 1
                 
                 ( (eq? (car L) y)  (set! z (- z 1))) ;check b and 2

                 (else (set! (= z z)));default

                 )
  ;if balance from this iteration has decreased then we have matched an ab in the cond
  (if (and (< z w) (> z 0));z must be positive otherwise a string starting with b would +1 result
      (count-xy x y z w (+ res 1) (cdr L))
      (count-xy x y z w res (cdr L))
  )
  )
  
  (let (ab (count 'a 'b 0 0 0 L)))
  (let (onetwo (count 1 2 0 0 0 L)))

  ((+ ab onetwo)) ) 
             
  
functional-programming scheme racket
1个回答
0
投票

你的代码存在大量问题;很明显你还没有真正掌握 Racket 的窍门。有些事情:

  • if
    需要三个参数:测试、真实情况和错误情况。
  • ((a b c))
    期望计算
    (a b c)
    的结果是一个可以用 0 个参数调用的函数。
  • (define (foo x) a b c)
    这样的函数将计算
    a
    b
    表达式并返回计算
    c
    的结果。如果
    a
    b
    没有副作用,那么包含它们就完全没有意义。
  • set!
    有其用途,但在 Racket 中不太鼓励使用。这个问题当然不需要。
  • let
    定义的变量仅在
    let
    的主体范围内。
  • count
    采用一个函数和一个或多个列表作为参数。
  • 你的缩进和格式到处都是。始终如一。 球拍风格指南有不错的建议。
  • 使用更有意义的变量名称,而不是像
    x
    y
    z
    这样的名称。
  • 你的函数的一般逻辑没有意义。

这是一个不完整的框架,可以提供一些如何解决上述问题的想法:

#lang racket/base

;;; Return true if the first element of lst is equal to val, otherise #f
;;; An empty list returns #f 
(define (head-is? lst val)
  ;; Implement this function
  #f)

(define (check-this tokens)
  ;; Look up "named let" if you haven't learned this form of let yet
  (let loop ([tokens tokens]
             [open-stack '()]
             [pair-count 0])
    (if (null? tokens)
        (if (null? open-stack) pair-count #f) ; Make sure there aren't any open symbols that need closing
        (case (car tokens) ; Dispatch based on the current token
          ((a) ; push a onto the stack of open tokens
           (loop (cdr tokens) (cons 'a open-stack) pair-count))
          ((b) ; if the head of the open stack is a, we've got a valid pair
           (if (head-is? open-stack 'a)
               (loop (cdr tokens) (cdr open-stack) (add1 pair-count))
               #f))
          ;; Handle the 1/2 cases also
          (else ; Ignore other tokens
            (loop (cdr tokens) open-stack pair-count))))))

(module+ test
  (require rackunit)
  (check-equal? (check-this '(a b a b)) 2)
  (check-equal? (check-this '(h e l l o)) 0)
  (check-equal? (check-this '(6 h a b a 1 h h i 2 b z)) 3)
  (check-equal? (check-this '(6 h a b a 1 h h i b z 2)) #f))
© www.soinside.com 2019 - 2024. All rights reserved.