找出Lisp中算术级数的差异

时间:2015-07-04 14:36:51

标签: math common-lisp

完全新的Lisp。

如何找到算术级数系列中元素之间的差异?

e.g。

(counted-by-N '(20 10 0))

返回-10

(counted-by-N '(20 10 5))
(counted-by-N '(2))
(counted-by-N '())

返回Nil

在Python / C和其他语言中,它非常简单......有点被困在Lisp中。

我的伪算法是这样的:

function counted-by-N(L):
    if len(L) <= 1:
        return Nil
    else:
        diff = L[second] - L[first]
        for (i = second; i < len(L) - 1; i++):
            if L[i+1] - L[i] != diff
                return Nil
        return diff

目前的工作:

(defun count-by-N (L)
    (if (<= (length L) 1) Nil
    (
        (defvar diff (- (second L) (first L)))
        ; How to do the loop part?
    ))
)

3 个答案:

答案 0 :(得分:2)

(flet ((by-n (list &aux
                   (e1 (first list))
                   (e2 (second list))
                   (difference (and e1 e2 (- e2 e1))))
         (and difference
              (loop for (one two) on list
                    while (and one two)
                    when (/= (- two one) difference)
                    do (return-from by-n nil)))
         difference))

  (by-n '(20 10 0)))

(flet ((by-n (list &aux
                   (e1 (first list))
                   (e2 (second list))
                   (difference (and e1 e2 (- e2 e1))))
         (when difference
           (loop for (one two) on list
                 while (and one two)
                 when (/= (- two one) difference)
                 do (return-from by-n nil))
           difference)))

  (by-n '(20 10 0)))

答案 1 :(得分:2)

就你在第二个答案中所说,你必须做的最佳选择就是递归实现它。

使用列表处理的示例(良好的方式)

这样,您可以通过一些方式以递归和简单的方式执行此示例:

(defun count-by-N-1 (lst)
  (if (equal NIL lst)
    NIL
    (- (car (cdr lst)) (car lst))
  )
  (count-by-N-1 (cdr lst))
)

关于函数count-by-N-1的第一种方法,我使用简单的carcdr指令来简化Common Lisp List转换的基础知识。

使用列表处理快捷方式的示例(最佳实现)

但是,您可以使用carcdr指令的一些快捷方式恢复,例如当您想要car cdr时,就像我在此做的那样例如:

(defun count-by-N-2 (lst)
  (if (equal NIL lst)
    NIL
    (- (cadr lst) (car lst))
  )
  (count-by-N-2 (cdr lst))
)

如果您使用Common Lisp List转换的基本说明以及carcdr来解决此类问题时遇到问题,您仍然可以选择first,{{ 1}}和second接近。不过,我建议您先看一些基本说明:

http://www.gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-processing.html

使用访问者的示例(最适合理解)

rest

最后一个,我将更清楚地解释,因为它是最容易理解的,你将做一个递归列表操作(如在其他例子中),和其他人一样,直到列表不是{{1它将获取列表其余部分的第一个元素,并减去同一列表的第一个元素。程序将对每个元素执行此操作,直到列表“干净”。最后返回带有减去值的列表。

如果您阅读并研究使用(defun count-by-N-3 (lst) (if (equal NIL lst) NIL (- (first (rest lst)) (first lst)) ) (count-by-N-3 (rest lst)) ) NILfirst方法与使用secondrest之间的相似性,那么您很容易理解我在这里做的两个第一个例子。

答案 2 :(得分:1)

以下是我使用递归的这个问题的最终答案:

.sitename