使用do循环无法在Lisp中求和 [英] Cannot do sum in lisp with do loop

查看:104
本文介绍了使用do循环无法在Lisp中求和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(defun suma (L)
  (setq var 0)
  (do 
      ((i 0 (+ i 1)))
      ((= i (length L)))
    (+ var (nth i L)))
  var)

为什么总是返回0?

它不应该返回列表L的总和吗?

Shouldn't it return sum of list L?

推荐答案

+ 不会修改其参数,因此,由于您从未修改var,因此将返回其初始值0.

+ does not modify its arguments, so, since you never modify var, its initial value of 0 is returned.

您需要将(+ var (nth i L))替换为与(setq var (+ var (nth i L)))等效的(incf var (nth i L)).

You need to replace (+ var (nth i L)) with (incf var (nth i L)), of, equivalently, (setq var (+ var (nth i L))).

请参见 incf .

请注意,您应将var let 绑定,而不是 setq .

Note that you should bind var with let instead of making it global with setq.

最重要的是,请注意,您的算法在list参数的长度上是二次的(因为 nth 每次都从头开始扫描您的列表.

Most importantly, note that your algorithm is quadratic in the length of the list argument (because nth scans your list every time from the start).

以下是一些更好的实现:

Here are some better implementations:

(defun sum-1 (l)
  (reduce #'+ l))

(defun sum-2 (l)
  (loop for x in l sum x))

(defun sum-3 (l)
  (let ((sum 0))
    (dolist (x l sum)
      (incf sum x))))

这是一个实现:

(defun sum-4 (l)
  (apply #'+ l))

sum-4的问题是,如果提供的列表的长度大于

The problem with sum-4 is that it will fail if the length of the supplied list is larger than call-arguments-limit.

这篇关于使用do循环无法在Lisp中求和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆