2016-11-13 236 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) 
相關問題