本程序应该在列表中找到每个符号,该符号位于某个符号之后。 该函数获取传入的参数。可以包含嵌套列表和符号的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)
问题可能在我的利弊声明中,我无法解决这个问题。
答案 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)))))))))
即便如此,我仍然无法遵循您的逻辑。例如,当某些内容为缺点时,您应该同时处理car
和cdr
,但不要处理。{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}}