方案递归错误

发布于 2024-10-01 19:29:56 字数 731 浏览 4 评论 0原文

这个递归函数似乎工作正常,将我想要的确切字母 B 和 C 添加到结果列表中,然后当它完成时,它正确地看到已到达最后一个元素。

然后它执行基本情况,并发生一个我无法解释的错误。是什么导致了这个错误?

    (define(preceding-R X Vector result)    
      (if (eq? '() (cdr (vector->list Vector)))
               result
              (helper X Vector result)))

(define (helper X Vector result)
   (if(eqv? X (cadr (vector->list Vector))) ((set! result (cons result (car (vector->list Vector)))) (preceding-R X (list->vector (cdr (vector->list Vector))) result))
                            (preceding-R X (list->vector (cdr (vector->list Vector))) result)))

(preceding-R 'a #(b a c a) '()))

错误:

程序应用:预期程序,给定:#;参数为:((() . b) . c)

This recursive function seems to work properly, adding to the result list the exact letters I want it to, B and C, and then when it finishes, it correctly sees that the last element has been reached.

It then executes the base case, and an error occurs which I cannot explain. What is causing this error?

    (define(preceding-R X Vector result)    
      (if (eq? '() (cdr (vector->list Vector)))
               result
              (helper X Vector result)))

(define (helper X Vector result)
   (if(eqv? X (cadr (vector->list Vector))) ((set! result (cons result (car (vector->list Vector)))) (preceding-R X (list->vector (cdr (vector->list Vector))) result))
                            (preceding-R X (list->vector (cdr (vector->list Vector))) result)))

(preceding-R 'a #(b a c a) '()))

The error:

procedure application: expected procedure, given: #; arguments were: ((() . b) . c)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

和我恋爱吧 2024-10-08 19:29:56

这里有一些代码并不是“绝对可怕”:

(define preceding-R 
  (lambda (x vec)
    (define helper
      (lambda (ls)
        (cond
          ((null? ls) '())
          ((null? (cdr ls)) '())
          ((eq? (cadr ls) x) (cons (car ls) (helper (cdr ls))))
          (else (helper (cdr ls))))))
    (helper (vector->list vec))))

> (preceding-R 'a #(b a c a))
(b c)

Eli Barzilay 有一个观点;如果我对原始代码进行评分,我可能会授予不到一半的学分,因为他指出了以下几点:

  • 在大多数情况下应该避免 set!,并且通常不允许涉及基本的家庭作业问题方案代码。必须使用 set! 通常表明递归还没有被很好地理解。
  • 由于 begin “丢弃”除最后一个表达式之外的所有内容的结果,这意味着非尾部表达式具有副作用(如 set!),因此 begin 通常也不会出现在教育问题中。
  • 一遍又一遍地来回转换显然是一种浪费。一次转换就可以了,但是您可能一开始就可以使用列表而不是向量。列表是Scheme 中最常用的数据结构,特别是因为它们与递归配合得很好。
  • 您的代码将在第二行的空列表中出错: (preceding-R 'a #()) =>;错误:尝试将 cdr 应用于 '()
  • 如果您确实使用 set! 来修改结果,则没有理由传递结果。这是额外的行李。
  • Eli 的最后一点是你可以写:

(define (helper X Vector result)
  (preceding-R X (list->vector (cdr (vector->list Vector)))
               (if (eq? X (cadr (vector->list Vector)))
                   (cons (car (vector->list Vector)) result)
                   result)))

节省一些重复的代码。

Here's some code that isn't "absolutely horrible":

(define preceding-R 
  (lambda (x vec)
    (define helper
      (lambda (ls)
        (cond
          ((null? ls) '())
          ((null? (cdr ls)) '())
          ((eq? (cadr ls) x) (cons (car ls) (helper (cdr ls))))
          (else (helper (cdr ls))))))
    (helper (vector->list vec))))

> (preceding-R 'a #(b a c a))
(b c)

Eli Barzilay has a point; if I were grading the original code, I would probably award fewer than half credit because of the things he pointed out:

  • set! should be avoided in most circumstances, and is generally not permitted on homework problems involving basic Scheme code. Having to use set! is a usual tell that recursion isn't understood too well.
  • Since begin "throws away" the results of everything but the last expression, it means that the non-tail expressions had side-effects (like set!) and so begin usually doesn't show up in educational problems either.
  • Conversion back-and-forth over and over and over and over again is obviously a waste. One conversion will do, but you probably could've used lists instead of vectors to begin with. Lists are the most common data structure used in Scheme, especially since they work well with recursion.
  • Your code will error out on an empty list in your second line: (preceding-R 'a #()) => Error: Attempt to apply cdr on '()
  • If you do use set! to modify result, then there's no reason to pass result around. It's extra baggage.
  • Eli's last point was that you can write:

.

(define (helper X Vector result)
  (preceding-R X (list->vector (cdr (vector->list Vector)))
               (if (eq? X (cadr (vector->list Vector)))
                   (cons (car (vector->list Vector)) result)
                   result)))

saving some repeated code.

━╋う一瞬間旳綻放 2024-10-08 19:29:56
(define (preceding-R X Vector result)    
  (if (eq? '() (cdr (vector->list Vector)))
    result
    (helper X Vector result)))

(define (helper X Vector result)
  (if (eqv? X (cadr (vector->list Vector)))
    (begin
      (set! result (cons (car (vector->list Vector)) result))
      (preceding-R X (list->vector (cdr (vector->list Vector))) result))
    (preceding-R X (list->vector (cdr (vector->list Vector))) result)))

(preceding-R 'a #(b a c a) '())

我添加了开始通话。如果你想要多个表达式,如果你不能将它们包装在 () 中,它会被解释为对 void 的函数调用(由 set 返回!),参数由对前面的 -R 的递归调用返回。

(define (preceding-R X Vector result)    
  (if (eq? '() (cdr (vector->list Vector)))
    result
    (helper X Vector result)))

(define (helper X Vector result)
  (if (eqv? X (cadr (vector->list Vector)))
    (begin
      (set! result (cons (car (vector->list Vector)) result))
      (preceding-R X (list->vector (cdr (vector->list Vector))) result))
    (preceding-R X (list->vector (cdr (vector->list Vector))) result)))

(preceding-R 'a #(b a c a) '())

I've added begin call. If you want multiple expressions in if you can't just wrap them in (), it was interpreted as function call on void (returned by set!) with argument returned by recursive call to preceding-R.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文