如何使用Lisp中的迭代函数打印列表中奇数位置的元素?

时间:2017-03-29 19:20:21

标签: lisp common-lisp

我必须在lisp中创建一个递归函数,它接受一个列表并生成另一个列表,其中只包含给定列表中奇数位置的元素。

如果我(1 2 3 4 5),我必须输出(1 3 5)

我的代码在这里:

(defun pozpar(lst) (do(
(l lst (cddr l)) 
(x '() (cons x (car l))))
((null l) x)))

输出:

(5 3 1)

我知道cons在开头添加了元素,我尝试使用appendlist,但没有任何效果。

3 个答案:

答案 0 :(得分:1)

最简单的方法是reverse结果:

(defun pozpar (lst)
  (do ((l lst (cddr l))
       (x '() (cons (car l) x)))
      ((null l)
       (nreverse x))))

(pozpar '(1 2 3 4 5))
==> (1 3 5)

注释

  1. 返回,而非输出您想要的值。

  2. 预先设置值并恢复结果是一种常见的Lisp编码模式。

  3. 由于append在其参数的长度上是线性,因此在循环中使用它会产生二次代码。

  4. 我在standard Lisp way中格式化了代码。如果您使用此样式,lispers将更容易阅读您的代码,因此更愿意帮助您。

答案 1 :(得分:1)

使用Private Sub CommandButton1_Click() Application.ScreenUpdating = False Dim copySheet As Worksheet Dim pasteSheet As Worksheet Dim ii As Long Set copySheet = Worksheets("Sheet3") Set pasteSheet = Worksheets("Sheet2") For ii = 1 To 10 copySheet.Range("A1:E3").Copy pasteSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues Application.CutCopyMode = False Application.ScreenUpdating = True Dim j, k, L, b As String Dim i As Long Dim wb As Workbook Dim sht1 As Worksheet Dim sht2 As Worksheet Set wb = ThisWorkbook Set sht1 = wb.Sheets("Sheet1") Set sht2 = wb.Sheets("Sheet2") j = "Name" b = "City" For i = 1 To 3 k = sht1.Range("A" & i) L = sht1.Range("B" & i) sht2.Cells.Replace what:=j, replacement:=k, lookat:=xlWhole, MatchCase:=False sht2.Cells.Replace what:=b, replacement:=L, lookat:=xlWhole, MatchCase:=False Next i Next ii End Sub ,您可以很容易地按照处理顺序获取元素。它也是最有效的,也是唯一一个可以使用所有长度参数的人:

loop

如果你真的想要递归,我会用一个带有线性更新的累加器来完成它:

(defun pozpar1 (lst)
  (loop :for e :in lst :by #'cddr 
        :collect e)))

然而,经典的非尾递归版本看起来像这样:

(defun pozpar2 (lst)
  (labels ((helper (lst acc)
             (if (endp lst)
                 (nreverse acc)
                 (helper (cddr lst) (cons (car lst) acc)))))
    (helper lst '())))

答案 2 :(得分:0)

我认为这是一种更简单的解决方案:

(defun popzar (lst)
  (cond
  ((null lst) nil)
  ( t (cons  (car lst) (popzar (cdr (cdr lst)))))
))

它首先检查列表是否为空,如果不是,它会创建一个包含第一个元素的新列表,以及使用列表的其余部分再次调用自身的结果,除了第二个元素。