我有一个函数,它将2个列表作为输入,我想这样做,以便第一个列表中的所有内容与第二个列表中的所有内容相乘,然后计算总和。
到目前为止,这是我的功能:
(defun multiply(a b)
(if (eq a nil)
0
(progn
(* (car a) (car b))
(multiply (car a) (cdr b)))
))
目前,我正试图让它做的是从第一个列表中取第一个数字,然后将第一个数字与第二个列表中的所有数字相乘。但是,当在函数中重新调用函数时,我收到此错误:
(这是我输入的,'(1 2 3)和'(4 5 6))
值1不是类型列表。
(MULTIPLY 1'(5 6))
非常感谢任何帮助。
答案 0 :(得分:7)
loop
可以接受吗?
案例1
如果结果 90 ,则
(+ (* 1 4) (* 1 5) (* 1 6) (* 2 4) (* 2 5) (* 2 6) (* 3 4) (* 3 5) (* 3 6))
然后你可以做
(defun multiply (a b)
(loop for i in a
sum (loop for j in b
sum (* i j))))
案例2
如果结果应该是 32 ,如
(+ (* 1 4) (* 2 5) (* 3 6))
然后就是
(defun multiply (a b)
(loop
for i in a
for j in b
sum (* i j)))
答案 1 :(得分:6)
如果你想为每个元素乘以两个列表,你应该只能使用mapcar:
(mapcar #'* '(3 4 5) '(4 5 6))
对于现有函数中的错误,此行应为:
...
(multiply (cdr a) (cdr b)))
...
答案 2 :(得分:3)
您所描述的内容听起来像dot product:
(defun dot (l1 l2)
(reduce #'+ (mapcar #'* l1 l2)))
上述解决方案很好,因为它纯粹是功能性的,但是,唉,它会创建一个不必要的中间列表。当然,Sufficiently Smart Compiler应该能够消除这一点,但实际上,您最好使用loop
:
(defun dot (l1 l2)
(loop for x in l1 and y in l2 sum (* x y)))
另请注意,使用list
代表mathematical vectors不是一个好主意,请改用vector
。
答案 3 :(得分:1)
我会将multiply
修改为
(defun multiply(a b)
(if (eq a nil)
0
(+
(* (car a) (car b))
(multiply (cdr a) (cdr b)))))
致电时
(multiply '(1 2 3) '(4 5 6))
它将返回总和
32
答案 4 :(得分:0)
(define (*2Ls L1 L2)
(apply map * (list L1 L2)))