Recursion 球拍';列表参考号';实施半工作制

Recursion 球拍';列表参考号';实施半工作制,recursion,scheme,racket,Recursion,Scheme,Racket,这是我之前工作的一个问题。我们目前正在用DrRacket在Racket中编程,并且在学期初刚刚完成对自然递归的复习 具体的问题是通过在中完成嵌套的第n个cdr来完成list ref的实现。下面是给出的代码: (define list-ref (lambda (ls n) (letrec ((nth-cdr (lambda (n) ;;body of function (car (nth-cdr n))))) 非常简单,指令是实现自

这是我之前工作的一个问题。我们目前正在用DrRacket在Racket中编程,并且在学期初刚刚完成对自然递归的复习

具体的问题是通过在中完成嵌套的第n个cdr来完成
list ref
的实现。下面是给出的代码:

(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)))))
通过
n个cdr
0
以外的任何数字都会导致
letrec
车身中的
car
发生“合同违约”

(list-ref '(1 2 3) 0) ==> '1
(list-ref '(1 2 3) 1) ==> *expected: pair?* *given: 2*
nth cdr
内的
ls
范围是否有问题?我不知道为什么
let rec
的主体会拿走
n个cdr n
car
并抱怨输出


有人知道这个可能非常简单的问题的答案吗

您的助手过程必须同时在列表和索引上前进,只减少数字是不行的。它应该称自己,而不是外部程序!此外,进行一点错误检查也不会有什么坏处,请尝试以下方法:

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

您的助手过程必须同时在列表和索引上前进,而不是仅仅减少数字。它应该称自己,而不是外部程序!此外,进行一点错误检查也不会有什么坏处,请尝试以下方法:

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

您的助手过程必须同时在列表和索引上前进,而不是仅仅减少数字。它应该称自己,而不是外部程序!此外,进行一点错误检查也不会有什么坏处,请尝试以下方法:

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

您的助手过程必须同时在列表和索引上前进,而不是仅仅减少数字。它应该称自己,而不是外部程序!此外,进行一点错误检查也不会有什么坏处,请尝试以下方法:

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

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

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

更新:你说你的解决方案必须遵循模板?这里有一个简单的方法,但与Ó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)))))

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

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

更新:你说你的解决方案必须遵循模板?这里有一个简单的方法,但与Ó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)))))

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

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

更新:你说你的解决方案必须遵循模板?这里有一个简单的方法,但与Ó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)))))

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

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

更新:你说你的解决方案必须遵循模板?这里有一个简单的方法,但与Ó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)))))


呵呵呵呵,英雄所见略同(这是你最近的一次编辑,而不是我的答案)。好吧,我的道歉,更正原代码!我忘了在原稿中添加
lamba(n)
,也忽略了这样一个事实,即我实际上仅限于在
nth cdr
中更改/添加代码。不幸的是,本课程目前的目标是以艰难的方式完成任务,对于这个特定的问题,这意味着使用提供的确切“模板”。甚至可以通过实现
nth crd
使函数工作吗?@BimmerM3不,除非在
nth cdr
中对
ls
进行变异,否则该函数不会工作。您可以保留
ls
而不是
(car ls)
,并在
nth cdr
之外执行此操作(实际上是一个常见的lisp名称。方案名称是
list tail
),就像在模板中一样。你确定助手中没有两个参数吗?我添加了一个遵循模板的版本,但没有使用
set。但它仍然很丑陋,因为它利用了Scheme的动态类型…;-)@BimmerM3那么,哪个版本最能解决你的问题呢?呵呵,伟大的头脑都是这样想的(这是你最近的编辑,而不是我的答案)。好的,我道歉,更正原始代码!我忘了