【问题标题】:How can i get all possible combinations of sets and subsets of a list that satisfy conditions with Common Lisp如何获得满足 Common Lisp 条件的列表的集合和子集的所有可能组合
【发布时间】:2015-11-13 17:24:05
【问题描述】:

对于 L = (A B C D) 的元素列表,要生成满足元素字典顺序 (A

【问题讨论】:

  • 您的意思是每个子集中的元素是有序的,还是您要按顺序获取子集,或者两者兼而有之?您的示例同时显示了两者,但我不确定这是否是您的问题所要求的。

标签: lisp common-lisp clisp


【解决方案1】:

lexicographical(非词法)顺序可以通过以下函数获得,该函数检查列表a是否在列表b之前按字典顺序:

(defun lex<= (a b)
  (or (null a)
      (and b 
           (string<= (car a) (car b))
           (lex<= (cdr a) (cdr b)))))

因此,您可以生成所有组合,就像在 coredump 的答案中一样,然后使用 (sort result #'lex&lt;=) 对它们进行排序。

【讨论】:

  • (sort (powerset '(a b c d)) #'lex&lt;=) 或者,如果你想从结果中消除nil(sort (remove nil (powerset '(a b c d))) #'lex&lt;=)powerset 在 coredump 的答案中定义。
  • 如果我没看错,那么排序会将nil 值放在排序范围的开头。排序后删除它们显然是更好的选择。
【解决方案2】:

看起来您只需编写简单的函数来获取列表的幂集,然后只需删除一个空集,并以您想要的任何方式对其进行排序。

(defun powerset (lst)
  (if lst (mapcan (lambda (el) (list (cons (car lst) el) el))
                (powerset (cdr lst)))
      '(())))

CL-USER> (powerset '(A B C D))
((A B C D) (B C D) (A C D) (C D) (A B D) (B D) (A D) (D) (A B C) (B C) (A C)
 (C) (A B) (B) (A) NIL)

要准确获得您的描述输出,您可以删除 NIL 并将其反转:

CL-USER> (reverse (remove nil (powerset '(A B C D))))
((A) (B) (A B) (C) (A C) (B C) (A B C) (D) (A D) (B D) (A B D) (C D) (A C D)
 (B C D) (A B C D))

这是你想要的吗?

更新。抱歉,没有提到您希望它以另一种方式排序。你应该使用它:

CL-USER> (sort 
           (reverse
             (remove nil
                     (powerset '(A B C D))))
             #'< :key #'length)
((A) (B) (C) (D) (A B) (A C) (B C) (A D) (B D) (C D) (A B C) (A B D) (A C D)
 (B C D) (A B C D))

这是另一个更重要的解决方案,使用loop 宏,按照您的描述进行:

(defun combinations (lst)
  (loop :for i :below (expt 2 (length lst))
        :when (loop :for j :below i :for el :in lst if (logbitp j i) :collect el)
        :collect it :into result
        :finally (return (sort result #'< :key #'length))))

CL-USER> (combinations '(A B C D E)) 
((A) (B) (C) (D) (E) (A B) (A C) (B C) (A D) (B D) (C D) (A E) (B E) (C E)
 (D E) (A B C) (A B D) (A C D) (B C D) (A B E) (A C E) (B C E) (A D E) (B D E)
 (C D E) (A B C D) (A B C E) (A B D E) (A C D E) (B C D E) (A B C D E))

【讨论】:

  • 不幸的是,有些组合不满足 (A (组合 '(A B C D E)) 需要看起来像 (A) (A B) (A B C) (A B C D) (A B C D E) (B) (B C) (B C D) (B C D E) (C) (C D) (C D E) (D) (D E) (E) 他们遵循词汇顺序 A
猜你喜欢
  • 2012-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-09
  • 2022-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多