在 Lisp 中找出等差级数的差异
Finding the difference in an arithmetic progression in Lisp
我完全 Lisp 新手。
如何找出等差级数中元素之间的差异?
例如
(counted-by-N '(20 10 0))
Return -10
(counted-by-N '(20 10 5))
(counted-by-N '(2))
(counted-by-N '())
Returns 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?
))
)
(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)))
这是我使用递归对这个问题的最终答案:
(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)
)
)
就你在第二个答案中所说的,你必须做这个例子的最佳选择是递归地实现它。
使用列表处理的示例(礼貌)
那样的话,您可以通过一些简单的递归方式来完成此示例:
(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
的第一种方法中,我使用简单的 car
和 cdr
指令来简化 Common Lisp 列表转换的基础知识。
使用列表处理快捷方式的示例(最佳实施)
但是你可以通过使用 car
和 cdr
指令的一些快捷方式来恢复,比如当你想做一个 cdr
的 car
时,就像我做的那样在这个例子中:
(defun count-by-N-2 (lst)
(if (equal NIL lst)
NIL
(- (cadr lst) (car lst))
)
(count-by-N-2 (cdr lst))
)
如果你在使用Common Lisp List转换的基本指令以及car
和cdr
理解这类问题时,你仍然可以选择first
, second
和 rest
方法。但是,我建议您先查看一些基本说明:
http://www.gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-processing.html
使用访问器的示例(最适合理解)
(defun count-by-N-3 (lst)
(if (equal NIL lst)
NIL
(- (first (rest lst)) (first lst))
)
(count-by-N-3 (rest lst))
)
最后一个,我将解释得更清楚,因为它是最容易理解的,您将进行递归列表操作(如其他示例中所示),并像其他示例一样,直到列表不是 NIL
它将获取列表其余部分的第一个元素并减去同一列表的第一个元素。该程序将为每个元素执行此操作,直到列表为 "clean"。最后 returns 减去值的列表。
这样,如果您阅读并研究了使用 first
、second
和 rest
方法与使用 car
和 cdr
方法之间的相似之处,您很容易将理解我在这里放的前两个例子。
我完全 Lisp 新手。
如何找出等差级数中元素之间的差异?
例如
(counted-by-N '(20 10 0))
Return -10
(counted-by-N '(20 10 5))
(counted-by-N '(2))
(counted-by-N '())
Returns 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?
))
)
(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)))
这是我使用递归对这个问题的最终答案:
(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)
)
)
就你在第二个答案中所说的,你必须做这个例子的最佳选择是递归地实现它。
使用列表处理的示例(礼貌)
那样的话,您可以通过一些简单的递归方式来完成此示例:
(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
的第一种方法中,我使用简单的 car
和 cdr
指令来简化 Common Lisp 列表转换的基础知识。
使用列表处理快捷方式的示例(最佳实施)
但是你可以通过使用 car
和 cdr
指令的一些快捷方式来恢复,比如当你想做一个 cdr
的 car
时,就像我做的那样在这个例子中:
(defun count-by-N-2 (lst)
(if (equal NIL lst)
NIL
(- (cadr lst) (car lst))
)
(count-by-N-2 (cdr lst))
)
如果你在使用Common Lisp List转换的基本指令以及car
和cdr
理解这类问题时,你仍然可以选择first
, second
和 rest
方法。但是,我建议您先查看一些基本说明:
http://www.gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-processing.html
使用访问器的示例(最适合理解)
(defun count-by-N-3 (lst)
(if (equal NIL lst)
NIL
(- (first (rest lst)) (first lst))
)
(count-by-N-3 (rest lst))
)
最后一个,我将解释得更清楚,因为它是最容易理解的,您将进行递归列表操作(如其他示例中所示),并像其他示例一样,直到列表不是 NIL
它将获取列表其余部分的第一个元素并减去同一列表的第一个元素。该程序将为每个元素执行此操作,直到列表为 "clean"。最后 returns 减去值的列表。
这样,如果您阅读并研究了使用 first
、second
和 rest
方法与使用 car
和 cdr
方法之间的相似之处,您很容易将理解我在这里放的前两个例子。