loops - 如何在 lisp 中生成一个笛卡尔积?

标签 loops lisp common-lisp generator cartesian-product

这是我生成笛卡尔积的代码:

(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)

最佳答案

您的第一个代码确实可以正常工作。

(defun cartesian-product (list)
  (loop
    for x in list
    nconc (loop for y in list
                collect (list x y))))

'(a b c) 调用它返回一个列表:

((A A) (A B) (A C) (B A) (B B) (B C) (C A) (C B) (C C))

您想避免构建列表并改用回调。 为了简化,首先尝试只打印元素而不是收集它们。

这意味着您不关心返回生成的值 取决于调用者:您只想生成它们并将它们打印为 一旦可用。

基本上,您可以将所有nconccollect 关键字替换为do,并添加对print 的调用:

(defun cartesian-product (list)
  (loop
    for x in list
    do (loop for y in list
             do (print (list x y)))))

使用 '(a b c) 对 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)))))

同样,您可以测试它是否仍像以前一样工作。

关于loops - 如何在 lisp 中生成一个笛卡尔积?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49869728/

相关文章:

graphics - 使用 SDL2 和 Lisp 的多个图形窗口?

java - 根据用户输入打破 while 循环

java - 非常简单的for循环错误Java

lisp - format - 帮助打印表格

lisp - 为什么阅读器宏扩展不传播到运行时(读取)?

emacs - 如何让 C-x C-e 只显示十进制和十六进制?

r - 像普通的 lisp 一样写 R

lisp - Common Lisp 中 WAR 文件的等价物

javascript - 尝试编写一个循环语句来打印我的播放列表,但我的浏览器只是无限循环

javascript - 函数或循环不工作