Scheme 是否将列表作为参数函数传递?
我试图在scheme中创建一个简单的函数,用于查找列表中的最大数字 这是我的密码:Scheme 是否将列表作为参数函数传递?,scheme,Scheme,我试图在scheme中创建一个简单的函数,用于查找列表中的最大数字 这是我的密码: (define (maximo lista maximo_actual) (if (= lista ()) maximo_actual (let* ((primero maximo_actual) (segundo (car lista))) (if (> primero segundo)
(define (maximo lista maximo_actual)
(if (= lista ())
maximo_actual
(let* ((primero maximo_actual)
(segundo (car lista)))
(if (> primero segundo)
((maximo (cdr lista) primero))
((maximo (cdr lista) segundo))))))
我使用以下命令调用函数:
(maximo (list 6 3 2 8 9) 5)
程序将返回以下内容:
;ERROR: "programas.scm": =: Wrong type in arg1 (6 3 2 8 9)
; in expression: (#@= #@lista ())
; in scope:
; (lista maximo_actual) procedure maximo
; defined by load: "programas.scm"
我认为参数有问题。我正在学习scheme,不知道问题出在哪里。我的awnser是基于(基于scheme) 您的程序存在一些问题。第一,比较数字,而不是列表。其次,
()
是一个没有任何内容的函数,而不是一个列表。要创建空列表,请使用(list)
或”()
。最后,((maximo(cdr lista)primero))
有一组额外的括号,这将导致执行(maximo(cdr lista)primero)
的结果。但是,(maximo(cdr lista)primero)
的结果是一个数字
我想您需要这样的东西,当使用(maximo(列表6 3 2 8 9)5)调用时,它将返回9
您也可以使用略短的
(define (maxio2 current result)
(if (> current result)
current
result))
(foldl maxio2 5 (list 6 3 2 8 9))
这是一个更惯用的Scheme过程,用于查找列表中的最大值:
(define (mi-maximo lista)
(if (empty? lista)
null
(maximo (rest lista) (first lista))))
(define (maximo lista maximo-actual)
(cond ((empty? lista) maximo-actual)
((> (first lista) maximo-actual)
(maximo (rest lista) (first lista)))
(else (maximo (rest lista) maximo-actual))))
注意,我引入了一个新过程,mi maximo
,用于调用helper过程maximo
,它完成了所有工作。对于有两个以上条件的情况,最好使用cond
,而不是一系列嵌套的if
。最后,最好使用empty?
或null?
来测试列表是否为空。按照以下步骤进行操作:
(mi-maximo '(1 2 3 4 5))
> 5
最后请注意,在Scheme(以及其他Lisp)中,您可以关闭同一行中的所有括号,而不是在单独的行中。它们不是花括号,你知道:)我对你的函数有四点看法:
- 您的错误是因为
=
运算符用于数值比较,而不是一般相等。为了测试列表是否为空,通常使用null?
函数李>
- 另外,对于
如果。。。然后。。。否则,如果…
某种语句,通常使用cond
,而不是if
- 你不需要
让*
在这里;取消拖动让
就行了。事实上,对于这个简单的函数,我完全不需要let
绑定
- 您真的应该使用传统的Lisp缩进,并将括号聚在一起
因此,您的功能,通过以下更改:
(define (máximo lista máximo-actual)
(cond ((null? lista)
máximo-actual)
((> (car lista) máximo-actual)
(máximo (cdr lista) (car lista)))
(else
(máximo (cdr lista) máximo-actual))))
但是,编写此函数的更高级方法是使用左折
,这是一种通用的列表迭代运算符,我们可以通过以下方式定义:
(define (fold-left función valor-corriente lista)
(if (null? lista)
valor-corriente
(fold-left función
(función (car lista) valor-corriente)
(cdr lista))))
fold left
对应于命令式语言中常见的for
-循环类型:
resultado = valor_inicial
for valor in valores:
resultado = función(valor, resultado)
return resultado
使用左折
和第二个辅助功能máximo de dos valores
,现在我们有了:
(define (máximo lista máximo-inicial)
(fold-left máximo-de-dos-valores máximo-inicial lista))
(define (máximo-de-dos-valores a b)
(if (> a b)
a
b))
这假设‘max’是一个内置程序,我认为大多数方案实施都会有。非常感谢,我是方案的noob:PWhy你称它为“PLT scheme”,如果你知道这个网站是为“Racket”…?它过去被称为“PLT scheme”。我想称它为“Racket”可能有点混乱。但显然,称之为“PLT方案”也令人困惑,我将编辑我的答案。
(define (máximo lista máximo-inicial)
(fold-left máximo-de-dos-valores máximo-inicial lista))
(define (máximo-de-dos-valores a b)
(if (> a b)
a
b))
(define (max-num lat)
(cond ((null? lat) (error "invalid list of numbers"))
((null? (cdr lat)) (car lat))
(else (max (car lat) (max-num (cdr lat))))))