List 在Lisp中不使用mapcar的情况下,将列表中的数字相乘(坐标方向)
我的代码输出有问题,我想是在检查列表的空值条件时 我试图完成的问题是:编写一个函数List 在Lisp中不使用mapcar的情况下,将列表中的数字相乘(坐标方向),list,recursion,lisp,vector-multiplication,List,Recursion,Lisp,Vector Multiplication,我的代码输出有问题,我想是在检查列表的空值条件时 我试图完成的问题是:编写一个函数vecmul,将两个简单的数字列表作为输入。vecmul应该像乘向量一样,按坐标乘这些列表。假设两个列表的长度相同。[例如,(vecmul'(2 3 4 5)'(1 4 5 2))返回(2*1 3*4*5*2)或(2 12 20 10)。不允许使用地图车来实现此功能] 到目前为止我有 (defun vecmul (list list2) (cond ((null list) 0) (t (cons (
vecmul
,将两个简单的数字列表作为输入。vecmul应该像乘向量一样,按坐标乘这些列表。假设两个列表的长度相同。[例如,(vecmul'(2 3 4 5)'(1 4 5 2))
返回(2*1 3*4*5*2)
或(2 12 20 10)
。不允许使用地图车来实现此功能]
到目前为止我有
(defun vecmul (list list2)
(cond ((null list) 0)
(t (cons (* (car list) (car list2))
(vecmul (cdr list) (cdr list2))))))
[170]> (setq l '(2 4 6))
(2 4 6)
[171]> (setq r '(1 3 5))
(1 3 5)
[172]> (vecmul l r)
(2 12 30 . 0)
我得到了正确的数字,只是列表在列表末尾添加了“.”和“0”。我很确定这是因为我没有正确地停止递归,或者没有正确地使用cond。我只是不完全确定如何纠正它。你几乎完全正确。但是,当正确的终止为nil
时,您将使用0
终止列表。此代码适用于:
(defun vecmul (list list2)
(cond ((null list) nil)
(t (cons (* (car list) (car list2)) (vecmul (cdr list) (cdr list2))))))
当您调用(cons12)
时,您得到的cons单元格将被写入(1.2)
。符号(123445)
仅仅是(1.(2.(3.(4.(5.nil);)
的简写。如果最后一个cons单元格的cdr
是6
,而不是nil
,那么您将得到(1.(2.(3.(4)(5.6)())
,简称为(1.2.3.4.5)
尼尔·福雷斯特回答了您的问题
再多说几句。在Lisp中使用现代名称:first
和rest
(defun vecmul (list1 list2)
(cond ((null list1) nil)
(t (cons (* (first list1) (first list2))
(vecmul (rest list1) (rest list2))))))
如果你有一个简单的正确和错误的决定,If
可能会更好。由于涉及列表操作,因此我将按如下方式编写,并且在
时不使用
(defun vecmul (list1 list2)
(if (null list1)
nil
(cons (* (first list1) (first list2))
(vecmul (rest list1) (rest list2)))))
最好在实代码中使用循环构造或映射。如上所述,递归具有堆栈深度限制。循环没有这个限制
(defun vecmul (list1 list2)
(loop for e1 in list1 and e2 in list2
collect (* e1 e2)))
或
(defun vecmul (list1 list2)
(mapcar #'* list1 list2))