(define min
(lambda (l m c)
(cond ((null? l) (print m))
(else ((c (car l))
if((< c m) (m c))
min((cdr l) m c))))))
我想用尾递归的方法来做,但它不起作用。我是Scheme的新手,希望你能帮助我。谢谢!
(define min
(lambda (l m c)
(cond ((null? l) (print m))
(else ((c (car l))
if((< c m) (m c))
min((cdr l) m c))))))
我想用尾递归的方法来做,但它不起作用。我是Scheme的新手,希望你能帮助我。谢谢!
这看起来像家庭作业,我会给你一些指示,以便你自己解决。填空:
(define (mymin lst minval)
(cond ((null? lst) ; If the list is empty
???) ; return the minimum value.
((< ??? minval) ; If current element < minimum value
(mymin ??? ???)) ; advance recursion, current element is new minimum.
(else ; If current element >= minimum value
(mymin ??? ???)))) ; advance recursion, keep the same minimum.
在上面的代码中,我们实现了一个双参数尾递归过程,称为mymin
(不要使用 name min
,这是一个内置过程。)第一个参数是要遍历的列表;第二个参数存储到目前为止找到的最小值,当递归结束时,它将保存答案。
像这样调用它,注意对于第一次调用,我们需要在第二个参数中传递一个非常大的数字,以至于所有其他数字都更小:
(mymin '(1 2 3 4 0 5) +inf.0)
> 0
Oscar 的版本会起作用,但我有一些风格上的小问题(这不是对 Oscar 的挖苦,他保持简单以使解决方案更简单)。如果你让它按照这些思路工作,看看你是否可以做一些改变。
无虚假参数
你有 3 个参数,Oscar 有两个,但这是一个接受一个输入的列表 - 一个列表。提供错误的额外种子参数,您将失败。解决此问题的一种方法是在 main 函数中重复出现。它可能看起来像这样
(define (mymin lst)
(let ((minval ???))
(define (findmin lst testval)
(cond
(????)
(????)
(????))
(findmin lst minval)))
你明白它是如何工作的吗?您可以将 minval 初始化为 inf.0,就像 Oscar 所做的那样,或者初始化为一个特殊的非数值(有几个不错的选择,一个比另一个更好)。
但是,如果您真的很聪明,您会发现没有必要每次都传递两个值。您可以将一个简单的对象传递给每个递归,而无需内部函数或任何初始化 - 当您一开始就拥有所需的所有数据时,为什么要初始化任何具有无限值的东西?
这是它的外观的线索(它的开头很像奥斯卡的版本):
(define (mymin lst)
(cond
((null? lst) ???)
((?????) (car lst))
(else (mymin (??????????????????????? lst)))))
???s的最后一行发生了一些事情;)
但是,只有在您拥有工作版本后才能尝试这些改进,除非您无法以任何其他方式使其工作。让它工作,然后改进——你学了两次;)
一路走来,有些事情要考虑...