Mic*_*lle 1 lisp loops generator common-lisp cartesian-product
这是我生成笛卡尔积的代码:
(defun cartesian-product (LIST)
(LOOP FOR X IN LIST
NCONC
(LOOP FOR Y IN LIST
COLLECT (LIST X Y))))
Run Code Online (Sandbox Code Playgroud)
我尝试输出其中一个笛卡儿产品:
(defun cartesian-product-generator (CALLBACK LIST)
(LOOP FOR X IN LIST
NCONC
(LOOP FOR Y IN LIST
DO(FUNCALL CALLBACK (LIST X Y)))))
Run Code Online (Sandbox Code Playgroud)
但是当我尝试使用以下测试时出现错误:
(cartesian-product-generator '(A B C))
Error: Too few arguments in call to #<Compiled-function cartesian-product-generator #x30200097E60F>:
1 argument provided, at least 2 required. While executing: cartesian-product-generator, in process listener(1).
Run Code Online (Sandbox Code Playgroud)
我是LISP的新手,想知道为什么会出现错误以及如何修复此错误.最终,我希望每次调用函数输出每个笛卡尔积.
例如,如果列表包含((1 1) (1 2) (2 1) (2 2)).我想生成(1 1).然后(1 2).然后(2 1).最后,(2 2).
您的第一个代码可以正常工作.
(defun cartesian-product (list)
(loop
for x in list
nconc (loop for y in list
collect (list x y))))
Run Code Online (Sandbox Code Playgroud)
调用它'(a b c)返回一个列表:
((A A) (A B) (A C) (B A) (B B) (B C) (C A) (C B) (C C))
Run Code Online (Sandbox Code Playgroud)
您希望避免构建列表并使用回调.为简化起见,首先尝试仅打印元素而不是收集它们.
这意味着您不必关心将生成的值返回给调用者:您只想生成它们并在它们可用时立即打印它们.
基本上,您可以替换所有nconc和collect关键字do,并添加一个调用print:
(defun cartesian-product (list)
(loop
for x in list
do (loop for y in list
do (print (list x y)))))
Run Code Online (Sandbox Code Playgroud)
对REPL的快速测试'(a b c)应该打印与之前相同的元素,每个元素都在separte行上.
现在,您可以概括print并调用您想要的任何内容:
(defun map-cartesian-product (function list)
(loop
for x in list
do (loop for y in list
do (funcall function (list x y)))))
Run Code Online (Sandbox Code Playgroud)
只是为了看它是否仍然有效,做一个快速测试:
(map-cartesian-product #'print '(a b c))
Run Code Online (Sandbox Code Playgroud)
这应该具有与以前相同的行为.
由于您只迭代一个副作用列表,您可以使用
DOLIST:
(defun map-cartesian-product (function list)
(dolist (x list)
(dolist (y list)
(funcall function (list x y)))))
Run Code Online (Sandbox Code Playgroud)
同样,您可以测试它仍然像以前一样工作.