Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scheme 长度[球拍]的2个尾部递归函数_Scheme_Racket - Fatal编程技术网

Scheme 长度[球拍]的2个尾部递归函数

Scheme 长度[球拍]的2个尾部递归函数,scheme,racket,Scheme,Racket,我试图编写两个独立的尾部递归函数来计算列表的长度,但我受到以下限制: 编写一个版本lengtht,它是尾部递归的,并根据需要使用外部非嵌套辅助函数 编写第二个版本lengtht2,它不使用额外的顶级函数。该函数仍然应该是尾部递归的,并且可以使用您想要的任何本地绑定 我是一个新手,这就是我所理解的尾部递归的一般形式: (define (func x) (cond (end-test-1 end-value-1) (end-test-2 end-value-2)

我试图编写两个独立的尾部递归函数来计算列表的长度,但我受到以下限制:

编写一个版本lengtht,它是尾部递归的,并根据需要使用外部非嵌套辅助函数

编写第二个版本lengtht2,它不使用额外的顶级函数。该函数仍然应该是尾部递归的,并且可以使用您想要的任何本地绑定

我是一个新手,这就是我所理解的尾部递归的一般形式:

(define (func x)
    (cond (end-test-1 end-value-1)
          (end-test-2 end-value-2)
          (else (func reduced-x))))

我只是有点搞不清楚如何做到这一点

本质上,尾部递归函数一直在调用自己,直到达到其结束条件。然而,与常规递归不同的是,它将中间答案传递给自己,直到到达终点

例如:

(define (find-length i lst)
  (if
    (null? lst) i
    (find-length (+ i 1) (cdr lst))))
该函数有两个值:i,它跟踪到目前为止列表的长度;lst,我们正在计算列表元素的列表。i、 出于所有目的,是我们对列表中元素的运行计数。因此,如果我们调用这个方法,我们将希望使用初始化为0的i来调用它

首先,我们检查列表是否为空。无效的如果列表为空,我们可以假设我们已经计算了所有元素,所以我们只需返回i,这是我们的运行计数。这是我们的最终条件

否则,我们将再次调用find length。然而,这次我们将i增加了1,并从列表cdrlst中删除了第一个元素

例如,假设我们这样调用函数:

(find-length 0 (list 2 3 4 3 5 3))
当我们评估时,程序将递归调用:

(find-length 1 '(3 4 3 5 3))
(find-length 2 '(4 3 5 3))
(find-length 3 '(3 5 3))
(find-length 4 '(5 3))
(find-length 5 '(3))
(find-length 6 '()) ; end condition, return 6

通常是尾部递归的一个很好的参考。

本质上,尾部递归函数一直在调用自己,直到达到其结束条件。然而,与常规递归不同的是,它将中间答案传递给自己,直到到达终点

例如:

(define (find-length i lst)
  (if
    (null? lst) i
    (find-length (+ i 1) (cdr lst))))
该函数有两个值:i,它跟踪到目前为止列表的长度;lst,我们正在计算列表元素的列表。i、 出于所有目的,是我们对列表中元素的运行计数。因此,如果我们调用这个方法,我们将希望使用初始化为0的i来调用它

首先,我们检查列表是否为空。无效的如果列表为空,我们可以假设我们已经计算了所有元素,所以我们只需返回i,这是我们的运行计数。这是我们的最终条件

否则,我们将再次调用find length。然而,这次我们将i增加了1,并从列表cdrlst中删除了第一个元素

例如,假设我们这样调用函数:

(find-length 0 (list 2 3 4 3 5 3))
当我们评估时,程序将递归调用:

(find-length 1 '(3 4 3 5 3))
(find-length 2 '(4 3 5 3))
(find-length 3 '(3 5 3))
(find-length 4 '(5 3))
(find-length 5 '(3))
(find-length 6 '()) ; end condition, return 6

一般来说,这是尾部递归的一个很好的参考。

这看起来像是家庭作业,所以我会给你一些提示,告诉你正确的方向,你可以填充空白。试着回答第一个问题:

(define (loop lst acc)              ; receives a list and an accumulator
  (cond ((null? lst) <???>)         ; if the list is empty return the accumulator
        (else (loop <???> <???>)))) ; advance the recursion, +1 to accumulator

(define (length1 lst)
  (loop <???> <???>))               ; how should we initialize the iteration?
(define (length2 lst)
  (letrec ((loop <???>)) ; lambda with the same procedure as the previous `loop`
    (loop <???> <???>))) ; start the recursion exactly the same as in `length1`
试着回答第二个问题:

(define (loop lst acc)              ; receives a list and an accumulator
  (cond ((null? lst) <???>)         ; if the list is empty return the accumulator
        (else (loop <???> <???>)))) ; advance the recursion, +1 to accumulator

(define (length1 lst)
  (loop <???> <???>))               ; how should we initialize the iteration?
(define (length2 lst)
  (letrec ((loop <???>)) ; lambda with the same procedure as the previous `loop`
    (loop <???> <???>))) ; start the recursion exactly the same as in `length1`

在任何情况下,想一想:空空空列表的长度是多少?答案将告诉您如何初始化迭代。对于这两种解决方案,我们使用一个额外的参数acc来跟踪到目前为止的答案,并将其与列表一起传递给一个循环尾递归过程。

这看起来像是家庭作业,因此我将给您一些提示,让您指出正确的方向,您可以填充空白。试着回答第一个问题:

(define (loop lst acc)              ; receives a list and an accumulator
  (cond ((null? lst) <???>)         ; if the list is empty return the accumulator
        (else (loop <???> <???>)))) ; advance the recursion, +1 to accumulator

(define (length1 lst)
  (loop <???> <???>))               ; how should we initialize the iteration?
(define (length2 lst)
  (letrec ((loop <???>)) ; lambda with the same procedure as the previous `loop`
    (loop <???> <???>))) ; start the recursion exactly the same as in `length1`
试着回答第二个问题:

(define (loop lst acc)              ; receives a list and an accumulator
  (cond ((null? lst) <???>)         ; if the list is empty return the accumulator
        (else (loop <???> <???>)))) ; advance the recursion, +1 to accumulator

(define (length1 lst)
  (loop <???> <???>))               ; how should we initialize the iteration?
(define (length2 lst)
  (letrec ((loop <???>)) ; lambda with the same procedure as the previous `loop`
    (loop <???> <???>))) ; start the recursion exactly the same as in `length1`

在任何情况下,想一想:空空空列表的长度是多少?答案将告诉您如何初始化迭代。对于这两种解决方案,我们使用一个名为acc的额外参数来跟踪到目前为止的答案,并将其与列表一起传递给一个循环尾递归过程。

这些过程是等效的,但最好将辅助函数隐藏在使用它们的过程中,因此首选第二种解决方案。第二个解决方案的另一个替代方案是使用一个命名的letmmm,我没有说清楚。在第二个函数中看到的循环只是必须定义的lambda的名称,lambda有两个参数,就像第一个函数中的循环一样-实际上,它们是相同的函数。充实了更多的细节,第一个长度2应该是这样的:lambda lst acc。。。。我们使用了一个letrec,因为lambda需要引用它自己,通过定义它的名称循环是的,填写缺少的。。。部分实际上与第一个循环相同。可能您没有正确地推进递归?我建议你看看小Schemer或如何设计程序,这两本书都会教你如何解决这类问题。程序是等价的,但最好是在使用它们的程序中隐藏辅助函数,所以最好使用第二种解决方案。第二个解决方案的另一个替代方案是使用一个命名的letmmm,我没有说清楚。你在第二页看到的循环
函数只是必须定义的lambda的名称,lambda有两个参数,就像第一个函数中的循环一样-实际上,它们是相同的函数。充实了更多的细节,第一个长度2应该是这样的:lambda lst acc。。。。我们使用了一个letrec,因为lambda需要引用它自己,通过定义它的名称循环是的,填写缺少的。。。部分实际上与第一个循环相同。可能您没有正确地推进递归?我建议你看看《小阴谋家》或者《如何设计程序》,这两本书都会教你如何解决这类问题