我必须在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
在开头添加了元素,我尝试使用append
或list
,但没有任何效果。
答案 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)
注释
此返回,而非输出您想要的值。
预先设置值并恢复结果是一种常见的Lisp编码模式。
由于append
在其参数的长度上是线性,因此在循环中使用它会产生二次代码。
我在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)))))
))
它首先检查列表是否为空,如果不是,它会创建一个包含第一个元素的新列表,以及使用列表的其余部分再次调用自身的结果,除了第二个元素。