lisp - 这个lisp函数可以递归实现吗?

标签 lisp common-lisp

此函数的目标是生成 2 列表的笛卡尔积。 例如

  • (组合(列表 1 2 3) (列表 4 5)) => (1 4) (1 5) (2 4) (2 5) (3 4) (3 5)

    (defun combo (l1 l2)
    (let    (
                (res (list))
            )
        (dolist (elem1 l1 res)
            (dolist (elem2 l2 res)
                (setq res (append res (list(list elem1 elem2))))
            )
        )
    )
    

    )

如何递归实现?

最佳答案

一个简单的递归实现是使用两个辅助函数;一个遍历 L1(下面代码中的 %COMBO),调用另一个函数将一个元素与 L2 中的每个元素配对(%PRODUCT):

(defun combo (l1 l2)
  (labels ((%product (el list &optional (acc (list)))
             (if (endp list)
                 acc
                 (%product el (rest list) (cons (list el (first list)) acc))))
           (%combo (l1 l2 &optional (acc (list)))
             (if (endp l1)
                 (nreverse acc)
                 (%combo (rest l1) l2 (nconc (%product (first l1) l2) acc)))))
    (%combo l1 l2)))

不过,迭代方法既简单又高效。不要在循环中使用 APPEND,您应该在最后反转列表。

(defun combo (l1 l2)
  (let ((res (list)))
    (dolist (e1 l1 (nreverse res))
      (dolist (e2 l2)
        (push (list e1 e2) res)))))

您也可以只使用 Alexandria 中的 MAP-PRODUCT 函数:

CL-USER> (ql:quickload :alexandria)
;=> (:ALEXANDRIA)
CL-USER> (use-package :alexandria)
;=> T
CL-USER> (map-product #'list (list 1 2 3) (list 4 5))
;=> ((1 4) (1 5) (2 4) (2 5) (3 4) (3 5))

关于lisp - 这个lisp函数可以递归实现吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37976330/

相关文章:

list - 为什么我的 lisp 函数给我这个输出?

algorithm - 就地插入排序 LISP

lisp - 如何安装 Movitz

lisp - Lisp 代码的缩进

lisp - 执行存储为列表的代码

lisp - cl-who 和格式

lisp - 为什么我的列表在 lisp 中不断 self 重置?

lisp - 比较 lisp 中的字符串

LISP FUNCTION - 返回列表中大于第一个元素的数字的计数

sorting - Common Lisp 连接和换行