首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Lisp中求算术级数的差

在Lisp中求算术级数的差
EN

Stack Overflow用户
提问于 2015-07-04 14:36:50
回答 3查看 280关注 0票数 1

我是对Lisp完全陌生。

如何在算术级数序列中找出元素之间的差异?

例如:

代码语言:javascript
复制
(counted-by-N '(20 10 0))

返回-10

代码语言:javascript
复制
(counted-by-N '(20 10 5))
(counted-by-N '(2))
(counted-by-N '())

返回Nil

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

我的伪算法应该是这样的:

代码语言:javascript
复制
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

目前的工作:

代码语言:javascript
复制
(defun count-by-N (L)
    (if (<= (length L) 1) Nil
    (
        (defvar diff (- (second L) (first L)))
        ; How to do the loop part?
    ))
)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-07-06 16:22:54

下面是我对这个问题的最后一个答案,它使用递归:

代码语言:javascript
复制
(defun diff (N)
    (- (second N) (first N))
)

(defun count-by-N (L)
    (cond
        ((null L)          nil)
        ((= (length L) 1)  nil)
        ((= (length L) 2) (diff L))
        ((= (diff L) (diff (rest L))) (count-by-N (rest L)))
        (T nil)
    )
)
票数 1
EN

Stack Overflow用户

发布于 2015-07-04 21:07:35

代码语言:javascript
复制
(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)))

代码语言:javascript
复制
(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)))
票数 2
EN

Stack Overflow用户

发布于 2015-07-07 17:55:07

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

使用列表处理的示例(良好的礼貌)

这样,您就可以在递归和简单的方法上执行这个示例:

代码语言:javascript
复制
(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指令来简化公共Lisp列表转换的基础知识。

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

但是,您可以通过使用一些carcdr指令的快捷方式来恢复工作,比如当您想要执行cdrcar时,就像我在这个示例中所做的那样:

代码语言:javascript
复制
(defun count-by-N-2 (lst)
  (if (equal NIL lst)
    NIL
    (- (cadr lst) (car lst))
  )
  (count-by-N-2 (cdr lst))
)

如果使用通用Lisp列表转换的基本说明以及carcdr来理解此类问题,仍然可以选择firstsecondrest方法。不过,我建议您先看看下面的一些基本说明:

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

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

代码语言:javascript
复制
(defun count-by-N-3 (lst)
  (if (equal NIL lst)
    NIL
    (- (first (rest lst)) (first lst))
  )
  (count-by-N-3 (rest lst))
)

最后一个,我将更清楚地解释,因为它是最容易理解的,您将执行递归列表操作(与其他示例一样),并且和其他示例一样,直到列表不是NIL为止,它将获得列表其余部分的第一个元素,并减去相同列表的第一个元素。程序将对每个元素执行此操作,直到列表“干净”为止。最后用减去的值返回列表。

这样,如果您阅读并研究了使用firstsecondrest方法与使用carcdr方法的相似之处,您将很容易理解我在这里介绍的这两个第一个示例。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31221824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档