【问题标题】:implement equal function to recursion function实现与递归函数相等的函数
【发布时间】:2016-01-12 13:47:22
【问题描述】:

我想修复我自己的函数,它与默认的交集函数给出相同的结果。我一直在尝试编写一个 lisp 代码,它在两个列表中打印相同的元素。我的代码适用于它。但它不适用于嵌套列表。我怎样才能解决这个问题?

(defun printelems (L1 L2) 
(cond 
((null L1) nil) ((member (first L1) L2) (cons (first L1) (printelems (rest L1) L2)))
(t (printelems (rest L1) L2))))

预期的输入和输出

(printelems '(2 3 5 7) '( 2 3)) => It works
=> (2 3)
(printelems '(a b '(c f)) '(a d '(c f) e)) => It doesn't work.
=> (a (c f))

编辑

使用默认的交集函数可以按预期工作。如何在递归函数中使用 equal 函数?

对于默认交叉点,

(intersection '(a b (c f)) '(a d (c f) e) :test 'equal)
((C F) A)
(intersection '(a b (c f)) '(a d c f e) :test 'equal)
(A)

我的路口,

(printelems  '(a b (c f)) '(a d c f e))
(A C F)
(printelems  '(a b (c f)) '(a d (c f) e) )
(A C F)

我编辑的代码:

(defun flatten (l)
  (cond ((null l) nil)
    ((atom (car l)) (cons (car l) (flatten (cdr l))))
    (t (append (flatten (car l)) (flatten (cdr l))))))

(defun printelemsv1(list1 list2)
  (cond
   ((null list1) nil)
   (((member (first list1) list2) (cons (first list1) (printelemsv1 (rest list1) list2)))
   (t (printelemsv1 (rest list1) list2)))))


(defun printelems (L1 L2)
   (printelemsv1 (flatten L1) (flatten L2)))

【问题讨论】:

  • 引用运算符' 仅在编写嵌套列表时需要在最外层列表中。 '(a b '(c f)) 应该是 '(a b (c f))。在 REPL 中测试您的版本并查看差异。 intersect 现在是否在 flatten 的帮助下工作,还是您仍有问题?
  • 它可以工作但不像预期的那样@AleArk

标签: list lisp common-lisp


【解决方案1】:

Common Lisp 已经有一个 intersection 函数。如果您想比较像 (CF) 这样的子列表,您需要使用 equalequalp 作为测试参数。

(intersection '(a b '(c f)) '(a d '(c f) e) :test 'equal)
;=> ('(C F) A)

虽然它不会改变 intersection 的工作方式,但您可能并不真正希望列表中包含 quoteQuote 不是列表创建运算符;这是一个“返回读者阅读的内容”运算符。读者可以将(ab (cf))读成两个符号的列表和一个子列表,所以(quote (ab (cf))),通常缩写为'(ab (cf)) 很好。例如:

(intersection '(a b (c f)) '(a d (c f) e) :test 'equal)
;=> ((C F) A)

【讨论】:

  • 我不确定你在问什么。您可以使用 intersection 计算公共元素。然后,您可以随心所欲地打印它们。
【解决方案2】:

提供输入示例和预期输出总是很有帮助的。我假设您的意思是您有两个列表,例如'(1 (2 3) 4)'((1) 2 5 6),该函数应生成'(1 2)。在这种情况下,您可以将两个列表展平,然后再将它们提供给printelems

由于我对 Common-Lisp 本身并不熟悉,所以我会给你一个例子和一个链接。

(defun flatten (structure)
  (cond ((null structure) nil)
        ((atom structure) (list structure))
        (t (mapcan #'flatten structure))))

Flatten a list - Rosetta Code

flatten 采用任意 s 表达式,如嵌套列表 '(1 (2 3) 4) 并返回 '(1 2 3 4)

所以现在您只需编写一个新函数,在其中使用您的 printelems 作为辅助函数并为其提供扁平列表。

(defun printelems.v2 (L1 L2)
   (printelems (flatten L1) (flatten L2)))

对此持保留态度,因为如前所述,我不熟悉 Common-Lisp,因此请提前对任何潜在的语法错误表示歉意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    • 2010-12-23
    • 2020-08-27
    相关资源
    最近更新 更多