【问题标题】:OR, AND a result from mapcar - lisp或者,以及来自 mapcar - lisp 的结果
【发布时间】:2018-02-18 11:52:28
【问题描述】:

我的任务是查找给定元素是否包含在列表(非线性列表)中。这是我现在写的,但是这个函数的返回值是一个列表,我真的不明白为什么。

(setq E 4)

(defun IsMember (L)
  (cond
    ((equal E L)
      T
    )

    ((atom L)
      NIL
    )

    (T
      (or (mapcar 'IsMember L))
    )
  )
)

(print (IsMember '(1 2 3 (((4) 5) 6))))

返回值为:(NIL NIL NIL (((T) NIL) NIL)) 但如果在给定列表中找不到E,它应该真正输出TNIL

【问题讨论】:

  • 一个参数的OR是什么?
  • 我想对包含TNIL的整个列表进行OR运算,最终结果是,如果列表中至少有一个T,则调用返回T,否则NIL,据我所知,mapcar 返回一个列表,但我仍然无法弄清楚这里出了什么问题
  • 但您不是在元素上应用 or,而是在列表本身上应用。更好地查看函数 SOME。
  • (some 'or (mapcar 'IsMember L)) -> *** - FUNCALL: OR is a special operator, not a function
  • 不要使用 OR 或 MAPCAR,使用 SOME

标签: lisp common-lisp logical-operators


【解决方案1】:

您的代码:

(defun is-member (l e)
  (cond

   ((equal e l)
    t)

   ((atom l)
    nil)

   (t
    (some #'(lambda (a)
              (if (equal t a) t nil))
          (mapcar #'(lambda (b) (is-member b e)) l)))))

摆脱 IF

你测试某个东西是否是 T,然后你返回 T。你可以摆脱它。

(defun is-member (l e)
  (cond

   ((equal e l)
    t)

   ((atom l)
    nil)

   (t
    (some #'(lambda (a)
              (equal t a))
          (mapcar #'(lambda (b) (is-member b e)) l)))))

摆脱 EQUAL

由于列表由 T 和 NIL 组成,EQUAL 也可以替换

(defun is-member (l e)
  (cond

   ((equal e l)
    t)

   ((atom l)
    nil)

   (t
    (some #'identity
          (mapcar #'(lambda (b) (is-member b e)) l)))))

摆脱 MAPCAR

由于 MAPCAR 返回 T 和 NIL 的列表,我们也可以删除它。

结果:

(defun is-member (list e)
  (cond ((equal list e)  t)
        ((atom list)     nil)
        (t               (some (lambda (b) (is-member b e))
                               list))))

摆脱 COND 条件/值对

由于 COND 像 OR 一样使用,我们可以将 COND 替换为 OR。我们不再需要条件/值对了:

(defun is-member (list e)
  (or (equal list e)
      (and (consp list)
           (some (lambda (b) (is-member b e))
                 list))))

【讨论】:

    【解决方案2】:

    您的解决方案可以更简单地重写为:

    (defun is-member (element tree)
      (flet ((recurse (e) (is-member e tree)))
        (or (equal element tree)
            (and (consp tree)
                 (some #'recurse tree)))))
    

    但你甚至不需要使用some

    (defun is-member (element tree)
      (or (equal element tree)
          (and (consp tree)
               (or (is-member element (car tree))
                   (is-member element (cdr tree))))))
    

    【讨论】:

      【解决方案3】:

      感谢帮助,设法不再使用 OR

      (defun IsMember (L E)
        (cond
          ((equal E L)
            T
          )
      
          ((atom L)
            NIL
          )
      
          (T
            (some #'(lambda (A) (if (equal T A) T NIL)
                  (mapcar #'(lambda (B) (IsMember B E)) L))
          )
        )
      )
      

      不确定道德是否足够,但能胜任...

      【讨论】:

      • 尝试摆脱MAPCAR,很简单。
      • 因此,如果您要搜索的不是 ll 是一个缺点,那么结果将是 tree-member-pcar cdr :-) 突然间它将适用于 (tree-member-p 4 '(3 . 4))
      猜你喜欢
      • 1970-01-01
      • 2013-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-04
      • 2015-11-14
      • 1970-01-01
      相关资源
      最近更新 更多