我需要一些帮助来理解尾递归
#lang racket
(define (lista x)
(printf(length(cons x (lista (read)))))
)
(lista (read))
我无法弄清楚如何结束链表的循环,然后获取长度并打印此数字。
例如,如果我有
的输入 2
1
3
5
7
5
10
它必须打印7,但编译器总是消息超时,所以我不知道我是否正确读取输入或者还有其他方法?
答案 0 :(得分:1)
你在做什么没有意义(我将在下面解释原因)。
如果您使用的是length
,则可以立即返回列表的长度。你有无限循环的原因是因为你没有停止条件(即当列表为null?
时结束递归)。
我认为这是一项要求您手动执行的操作,因此不使用length
。
(define (lngth lst)
(if (null? lst) ; Did we checked the whole list already?
0 ; This will put an end to the recursion !
(+ 1 ; Tail recursive call, we add 1 because we call ourselve recusrively with the cdr of the list (hence with a list that is one shorter)
(lngth (cdr lst)))))
现在您可以调用此过程,(lngth '(1 2 3 4 5))
将返回5.
(define (lista x)
(printf
(length
(cons x
(lista (read))))))
您的尝试有一些问题。最大的问题是它缺少一个停止条件,这就是无限循环的原因(它会一次又一次地提示用户输入)。现在当你拨打lista
时,由于(define (lista x) ... (cons x (lista ...)))
,你总是会一次又一次地遇到递归调用。
正如我上面所说,其余的代码并没有真正意义。
您使用cons
代替cdr
遍历列表,并且您正在使用length
而不是为列表的当前元素添加(+ 1 (recursive call))
。< / p>
答案 1 :(得分:0)
你在递归中没有停止条件,这就是为什么它继续而不打印长度。例如,您可以通过查找某个输入来中断,例如,“长度”来打印长度。
#lang racket
(define (get-length-of-input)
(display "Enter a number or get the length (length for length)")
(let input-loop ((result '()))
(define input (read-line))
(cond [(number? (string->number input))
(input-loop (cons input result))]
[(string=? input "length")
(displayln (length result))]
[else (displayln "unknown input")
(input-loop result)])))
; Start the procedure
(get-length-of-input)
这里使尾部递归,迭代循环与named-let 一起使用。 named-let使用初始值(空列表'()
)初始化循环并自动启动它。
然后进行案例分析(输入数字,字符串“长度”或其他什么?)。如果它是一个数字(通过尝试将输入字符串转换为数字来检查),则将此数字添加到局部变量result
并继续循环。如果输入为“长度”,则打印长度并停止程序。否则显示“未知输入”并继续循环。