Racket'list-ref'实现半工作

时间:2015-01-30 22:49:52

标签: recursion scheme racket

这是我之前作业的一个问题。我们目前正在使用DrRacket在Racket中进行编程,并且在学期初期就完成了对自然递归的审查。

具体问题是通过完成嵌套list-ref来完成nth-cdr的实施。这是给出的代码:

(define list-ref
  (lambda (ls n)
   (letrec
      ((nth-cdr
        (lambda (n)
         ;;body of function
    (car (nth-cdr n)))))

非常简单,说明是实现nth-cdr的自然递归版本。这就是我最终得到的结果:

(define list-ref
  (lambda (ls n)
   (letrec
       ((nth-cdr
        (lambda (n)
          (cond  
            ((zero? n) ls)
            (else (list-ref (cdr ls) (sub1 n)))
            ))))
     (car (nth-cdr n)))))

传递nth-cdr 0以外的任何号码都会导致合同违规行为发生。在car的正文中letrec

(list-ref '(1 2 3) 0) ==> '1
(list-ref '(1 2 3) 1) ==> *expected: pair?* *given: 2*

ls范围内nth-cdr的范围是否有问题?我不知道为什么let-rec的主体会接受car的{​​{1}}并抱怨输出?

任何人都有可能非常简单问题的答案吗?

2 个答案:

答案 0 :(得分:2)

list-ref很容易编写为尾递归函数:

(define (list-ref lst n)
  (if (zero? n)
      (car lst)
      (list-ref (cdr lst) (- n 1))))

更新:你说你的解决方案必须遵循模板吗?这是一种hacky方式,但与Óscar的解决方案不同,它不使用set!。但它仍然很难看:

(define list-ref
  (lambda (ls n)
    (letrec
        ((nth-cdr
          (lambda (n)
            (if (number? n)
                (nth-cdr (cons ls n))
                (let ((ls (car n))
                      (n (cdr n)))
                  (if (zero? n)
                      ls
                      (nth-cdr (cons (cdr ls) (- n 1)))))))))
      (car (nth-cdr n)))))

答案 1 :(得分:1)

你的帮助程序必须在列表和索引上前进,它不会只是递减数字。它应该自称,而不是外部程序!此外,一些错误检查不会受到影响,请尝试:

(define list-ref
  (lambda (ls n)
   (letrec
       ((nth-cdr
        (lambda (ls n)
          (cond
            ((null? ls) #f)
            ((zero? n) (car ls))
            (else (nth-cdr (cdr ls) (sub1 n)))
            ))))
     (nth-cdr ls n))))

要明确的是,这里真的不需要帮助程序,为了简化我们可以做到这一点:

(define list-ref
  (lambda (ls n)
    (cond
      ((null? ls) #f)
      ((zero? n) (car ls))
      (else (list-ref (cdr ls) (sub1 n))))))

<强>更新

既然你已经在评论中提到有一些额外的限制,我可以为你提供以下解决方案 - 它有效,但相信我,它很难看。我们不应该为这个简单的问题改变状态,这可以通过传递一个额外的参数来避免。无论如何,你走了:

(define list-ref
  (lambda (ls n)
    (letrec
        ((nth-cdr
          (lambda (n)
            (cond ((null? ls) '(#f))
                  ((zero? n) ls)
                  (else
                   (set! ls (cdr ls))
                   (nth-cdr (sub1 n)))))))
      (car (nth-cdr n)))))