在Lisp中乘以2个列表

时间:2013-12-26 22:14:36

标签: function lisp multiplying

我有一个函数,它将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))

非常感谢任何帮助。

5 个答案:

答案 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)))