这是我生成笛卡尔产品的代码:
(defun cartesian-product (LIST) (LOOP FOR X IN LIST NCONC (LOOP FOR Y IN LIST COLLECT (LIST X Y))))我尝试用这个输出一个笛卡尔产品:
(defun cartesian-product-generator (CALLBACK LIST) (LOOP FOR X IN LIST NCONC (LOOP FOR Y IN LIST DO(FUNCALL CALLBACK (LIST X Y)))))但是,当我尝试使用以下方法时出现错误:
(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).我是LISP的新手,想知道为什么会出现错误以及如何解决此错误。 最终,我希望每次调用函数都输出每个笛卡尔积。
例如,如果列表由((1 1) (1 2) (2 1) (2 2)) 。 我想生成(1 1) 。 然后(1 2) 。 然后(2 1) 。 最后, (2 2) 。
This is my code to generate a cartesian product:
(defun cartesian-product (LIST) (LOOP FOR X IN LIST NCONC (LOOP FOR Y IN LIST COLLECT (LIST X Y))))I tried outputting one of the cartesian products with this:
(defun cartesian-product-generator (CALLBACK LIST) (LOOP FOR X IN LIST NCONC (LOOP FOR Y IN LIST DO(FUNCALL CALLBACK (LIST X Y)))))However there are errors when I tried testing it with:
(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).I am new to LISP and would like to know why there's an error and how to fix this error. Ultimately, I would like to output each cartesian product per call of the function.
For example, if the lists consists of ((1 1) (1 2) (2 1) (2 2)). I would like to generate (1 1). Then (1 2). Then (2 1). Lastly, (2 2).
最满意答案
你的第一个代码确实工作正常。
(defun cartesian-product (list) (loop for x in list nconc (loop for y in list collect (list x y))))用'(abc)调用它会返回一个列表:
((A A) (A B) (A C) (B A) (B B) (B C) (C A) (C B) (C C))您希望避免构建列表并使用回调。 为了简化,首先尝试打印元素而不是收集元素。
这意味着您不必关心将生成的值返回给调用者:您只需生成这些值并在其可用时立即将其打印出来。
基本上,你可以替换所有nconc并通过do collect关键字,并添加一个print电话:
(defun cartesian-product (list) (loop for x in list do (loop for y in list do (print (list x y)))))用'(abc)对REPL进行快速测试应该打印与之前相同的元素,每个元素都在一个分隔线上。
现在,您可以简化print和打电话任何你想要的:
(defun map-cartesian-product (function list) (loop for x in list do (loop for y in list do (funcall function (list x y)))))只要看看它是否仍然有效,请做一个快速测试:
(map-cartesian-product #'print '(a b c))这应该和以前一样。
既然你只是遍历一个副作用列表,你可以使用DOLIST :
(defun map-cartesian-product (function list) (dolist (x list) (dolist (y list) (funcall function (list x y)))))再次,您可以测试它仍然像以前一样工作。
Your first code does work correctly.
(defun cartesian-product (list) (loop for x in list nconc (loop for y in list collect (list x y))))Calling it with '(a b c) returns a list:
((A A) (A B) (A C) (B A) (B B) (B C) (C A) (C B) (C C))You want to avoid building a list and use a callback instead. To simplify, first try to only print elements instead of collecting them.
That means that you do not care about returning the generated values up to the caller: you just want to generate them and print them as soon as they are available.
Basically, you can replace all nconc and collect keywords by do, and add a call to print:
(defun cartesian-product (list) (loop for x in list do (loop for y in list do (print (list x y)))))A quick test on the REPL with '(a b c) should print the same elements as previously, each one on a separte line.
Now, you can just generalize print and call anything you want:
(defun map-cartesian-product (function list) (loop for x in list do (loop for y in list do (funcall function (list x y)))))Just to see if it still works, do a quick test:
(map-cartesian-product #'print '(a b c))This should have the same behaviour as before.
Since you only iterate over a list for side-effects, you can use DOLIST:
(defun map-cartesian-product (function list) (dolist (x list) (dolist (y list) (funcall function (list x y)))))Again, you can test that it still works as previously.
更多推荐
发布评论