【问题标题】:In Lisp, how do you add a given element to every list inside a given list?在 Lisp 中,如何将给定元素添加到给定列表中的每个列表中?
【发布时间】:2013-01-22 22:06:01
【问题描述】:

这是我目前所拥有的:

(defun append-all(x L)
  (if (null L)
    L   
    (cons (append (car L) x) (append-all x (cdr L))))
  )
)

输出:

(append-all '3 '((1) (2 1) (2)))

((1 . 3) (2 1 . 3) (2 . 3))

想要:

((1 3) (2 1 3) (2 3))

这是一个辅助函数,所以它是一个链表这一事实似乎给我带来了问题。

谢谢

编辑:固定递归调用

【问题讨论】:

    标签: list functional-programming lisp common-lisp


    【解决方案1】:

    在您的代码中,更改此部分:

    (append (car L) x)
    

    到这里:

    (append (car L) (list x))
    

    它以前不起作用,因为append 应该接收两个列表作为参数,而不是一个列表和一个元素。

    【讨论】:

      【解决方案2】:
      (defun append-all (item list)
        "Appends ITEM to each sublist of LIST"
        (flet ((circular-list (item)
                 (let ((list2 (list item)))
                   (nconc list2 list2))))
          (mapcar #'append
                  list
                  (circular-list (list item)))))
      

      【讨论】:

      • 有趣的把戏。但是现在不需要flet(您可以将mapcar 移动到let 中并直接使用list2),如果它是为了可读性而存在,那么IMO 甚至更好地将(list item) 移出它所以呼叫变为(circular-list (list item))
      • @6502:我认为在 Lisp 中使用子函数来提高可读性被低估了。如果它具有通用性,那么将其移至顶层是有意义的。拥有一个函数已经让这变得更容易......
      • 我同意...但我会使用(flet ((circular-list (x) (let ((list2 (list x)) ...)。元素为 x 的循环列表比元素为 (list x) 的循环列表更有用。
      【解决方案3】:

      如果您不想自己进行递归,这也应该可行:

      (defun append-all (x L)
        (mapcar #'(lambda (l) (append l (list x))) L))
      

      【讨论】:

      • 请注意,对于标准阅读器大小写,所有符号都大写,因此lL 表示相同的符号名称。在显示的代码中,它按预期工作,因为 L 被遮住了。
      【解决方案4】:

      我正在学习 clisp,但它可以工作。

      (defun append-all (x L)
          (flet (
              (append-item (alist) (append alist (list x))))
              (mapcar #'append-item L)))
      
      (print (append-all '3 '((1) (2 1) (2))))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 2014-08-12
        • 1970-01-01
        • 2021-10-04
        • 1970-01-01
        相关资源
        最近更新 更多