LISP计划需要不小的调整。

时间:2014-11-02 20:08:27

标签: lisp symbols null cons

本程序应该在列表中找到每个符号,该符号位于某个符号之后。 该函数获取传入的参数。可以包含嵌套列表和符号的List。 该函数必须扫描列表并搜索给定的符号并打印给定符号后面的符号。

示例:

(find-all 'a '((b a) ((c a b)))) --> (c b)
 (find-all 'a '(b (a a) c)) --> (a c)
 (find-all 'a '(b d c e)) --> nil

我的代码:

(defun find-all (a list)
    (if (consp list)
        (if (consp (car list))
            (find-all a (car list))
        (if (eq a (car list))
            (cons (car(cdr list)) (find-all a(cdr list)))
            (find-all a(cdr list))))))

此代码有效,除非其查找的符号是列表中的最后一个原子。 它在这些测试用例中失败了:

 (find-all 'a '((b a) ((c a b)))) --> (c b)
 (find-all 'a '(b (a a) c)) --> (a c)

但在这些情况下工作正常:

(find-all 'a '(b a c a e)) --> (c e)

问题可能在我的利弊声明中,我无法解决这个问题。

1 个答案:

答案 0 :(得分:0)

我认为您的代码不正确。首先,它没有正确缩进,这使得它难以阅读。正确的缩进应该是:

(defun find-all (a list)
  (if (consp list)
      (if (consp (car list))
          (find-all a (car list))
          (if (eq a (car list)) ; if properly intended here
              (cons (car(cdr list)) (find-all a(cdr list)))
              (find-all a(cdr list)))))))))

即便如此,我仍然无法遵循您的逻辑。例如,当某些内容为缺点时,您应该同时处理carcdr,但不要处理。{1}}和(defun flatten (sxp) (labels ((sub (sxp res) (cond ((null sxp) res) ((consp sxp) (sub (car sxp) (sub (cdr sxp) res))) (t (cons sxp res))))) (sub sxp nil))) 。我没有经历调试过程,但你应该这样做。


相反,我想向您展示另一种选择。我建议将问题分为两部分:

展开列表

由于我们从嵌套列表开始,但最终得到一个平面列表,因此首先将列表更容易展平。这是一个经典的展平功能:

member

处理单位列表

现在,使用平面列表,其余部分变得显而易见,使用find-from函数(并调用我的函数(defun find-from (a lst) (labels ((sub (lst) (when lst (let ((rst (cdr (member a lst)))) (when rst (cons (car rst) (sub rst))))))) (sub (flatten lst)))) 将其与您的REPL区分开来):

? (find-from 'a '((b a) ((c a b))))
(C B)
? (find-from 'a '(b (a a) c))  
(A C)
? (find-from 'a '(b d c e)) 
NIL
? (find-from 'a '(b a c a e)) 
(C E)

<强>测试

{{1}}