如何在Scheme函数中声明变量?

如何在Scheme函数中声明变量?,scheme,Scheme,有可能吗?假设我想要得到列表的最后一个元素,我将创建一个变量I=0,并递增它直到它等于长度。有什么想法吗?请举个例子,不胜感激 谢谢,有几种方法可以声明变量;最干净的是让: (let ((x some-expr)) ; code block that uses x 但是您不需要这个来获取列表的最后一个元素。只需使用递归: (define (last xs) (if (null? (cdr xs)) (car xs) (last (cdr xs)))) 注意:如果需要,

有可能吗?假设我想要得到列表的最后一个元素,我将创建一个变量
I=0
,并递增它直到它等于长度。有什么想法吗?请举个例子,不胜感激


谢谢,

有几种方法可以声明变量;最干净的是让:

(let ((x some-expr))
  ; code block that uses x
但是您不需要这个来获取列表的最后一个元素。只需使用递归:

(define (last xs)
  (if (null? (cdr xs))
    (car xs)
    (last (cdr xs))))
注意:如果需要,可以使用变量缓存
cdr
的结果:

(define (last xs)
  (let ((tail (cdr xs)))
    (if (null? tail)
      (car xs)
      (last tail))))

是的,可以在scheme中定义局部变量,可以在函数中使用
let
define
。使用
set,也可以像您想象的那样重新分配变量

也就是说,你不应该用这种方式解决你的问题。在Scheme中,通常最好避免
设置当您不需要时(在这种情况下,您肯定不需要)。使用索引进一步迭代一个列表通常是一个坏主意,因为scheme的列表是链表,因此随机访问O(n)(使
最后一个
函数成为您想要实现的
O(n^2)


因此,一个没有索引的简单递归实现将比您计划执行的操作更为惯用,速度更快,因此更可取。

获取最后一个元素的算法是什么?@larsmans:遍历列表直到
i
等于长度?这听起来合理吗?这听起来像是浪费,因为你要遍历列表两次;第一次计算长度。该算法将是线性时间(不是@sepp2k假设的二次时间),但是两次通过,不是惯用的。谢谢。我的问题是从列表中删除最后一个元素。我可以反转列表,然后删除第一个元素,但它似乎效率太低。与其他传统语言如C或C++相比,在方案中的思维完全是奇特的。除了使用<代码> SET之外,还有其他方法来重新定义方案中的变量吗?代码>?非常感谢,非常好的解决方案!顺便说一下,我对上面的if语句有点困惑。
最后一个尾部是否属于
if
或它是一个单独的语句?我们如何区分?@Chan:
(最后一尾)
if
表达式的else部分。你可以从帕伦斯和我使用的缩进来判断。