2016-11-13 140 views
0

我想写一个函数,它接受2个列表作为参数并返回列表中的乘积。 这样的:将列表中的每个元素与另一个列表中的每个元素相乘lisp

(3 4)(3 5 6)=>(9 15 18 12 20 24)

这是我已经想出了的代码,但我接收被告知错误我对地图的论据太少了。

(defun multip (lst lst2) 
    ;this is a function to flatten the result 
    (defun flatten (tree) 
    (let ((result '())) 
     (labels ((scan (item) 
      (if (listp item) 
       (map nil #'scan item) 
       (push item result)))) 
        (scan tree)) 
         (nreverse result))) 
(flatten (map (lambda (i) (map (lambda (j) (* i j)) lst)) lst2)) 
) 

    (write (multip '(3 4 6) '(3 2))) 

我不明白我做错了什么。我感谢你的评论。

+0

仅供参考,您可以使用使用地图产品:'(亚历山大:地图产品# '*'(3 4)“(3 5 6))' – coredump

回答

3

您应该使用mapcar,而不是map

(mapcar (lambda (i) (mapcar (lambda (j) (* i j)) lst)) lst2)) 

这是两个不同的功能:mapcar地图上的一个或多个列表的功能,至少需要两个参数,而map是等效的,但是任何序列类型(例如向量),并且需要额外的参数来指定结果的类型。请参阅参考文献maphere,并参考mapcarhere

风格

您使用的是defun内的另一个defun:这是不好的风格,因为每一次multip被称之为全球重新定义了功能flatten。您应该定义flatten外,只有一次,或使用功能的局部声明与fletlabels(作为内部功能scanflatten。)

对于flatten另一种更简单的定义,你可以看到this question所以。

+0

由于运作良好。 – Shahryar

+0

是的,你是对的风格,我会读你介绍给我的资源。再次感谢。 – Shahryar

4

如果您创建一个扁平列表,则不需要扁平化列表。

使用MAPCAN:

CL-USER 4 > (flet ((mult (a b) 
        (mapcan #'(lambda (a1) 
           (mapcar (lambda (b1) (* a1 b1)) 
             b)) 
          a))) 
       (mult '(3 4) '(3 5 6))) 
(9 15 18 12 20 24) 
相关问题