Recursion 这个scheme函数似乎是尾部递归的,那么为什么会出现堆栈溢出呢
我最近几年来第一次在这个计划上胡闹。 我正在使用repl.it玩一玩。 我编写了这个基本函数来获取一个列表并返回一个双链接列表。列表的每个单元格都是一对,其car是列表元素,其cdr与car中的前一个元素和cdr中的下一个元素成对。第一个和最后一个元素的前一项和下一项分别为null。我编写的函数是尾部递归的。我现在知道scheme实际上有循环语法,但我在写它时的印象是,在scheme中循环的唯一方法是使用尾部递归。我的代码如下:Recursion 这个scheme函数似乎是尾部递归的,那么为什么会出现堆栈溢出呢,recursion,scheme,tail-recursion,Recursion,Scheme,Tail Recursion,我最近几年来第一次在这个计划上胡闹。 我正在使用repl.it玩一玩。 我编写了这个基本函数来获取一个列表并返回一个双链接列表。列表的每个单元格都是一对,其car是列表元素,其cdr与car中的前一个元素和cdr中的下一个元素成对。第一个和最后一个元素的前一项和下一项分别为null。我编写的函数是尾部递归的。我现在知道scheme实际上有循环语法,但我在写它时的印象是,在scheme中循环的唯一方法是使用尾部递归。我的代码如下: (define (dbllink li) (letrec
(define (dbllink li)
(letrec ((step (lambda (lis prev head)
(if (null? lis)
head
(let ((cell (cons (car lis)
(cons prev '()))))
(if (null? prev)
(step (cdr lis);<--recursive call
cell
cell)
(begin (set-cdr! (cdr prev)
cell)
(step (cdr lis);<--recursive call
cell
head ))))))))
(step li '() '())))
(定义(dbllink li)
(letrec)(步骤(lambda(lis上封头)
(如果(空?lis)
头
(let)单元(cons)单元(car lis)
(((()))
(如果(空?上一个)
(步骤(cdr lis);是的。您的代码确实是尾部递归的。当我在DrRacket的r6rs中尝试这一点时,我得到了
(dbllink '(1 2 3 4 5))
; ==> #0={1 () . #1={2 #0# . #2={3 #1# . #3={4 #2# 5 #3#}}}}
这形成了一个循环结构。我想也许BiwaScheme试图打印它,但你不能用尾部递归打印列表结构,它不会检查循环列表,所以你最终会出现堆栈溢出
您可以通过指定结果来验证这一点,这样它就不会打印结果
(define test (dbllink '(1 2 3 4 5)) ; ==> #void
(car test) ; ==> 1
test ; ("too much recursion" in Biwa)
嗯……它不应该是圆形的。也就是说,第一个元素和最后一个元素的下一个和上一个“字段”应该是空的。或者你的意思是,小圆圈是由连续的元素相互指向形成的?