0

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

例子:

(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)

问题可能出在我的缺点声明中,我无法解决此问题。

4

1 回答 1

0

I don't think your code is correct. First of all, it's not correctly indented, which makes it difficult to read. The correct indentation should be:

(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)))))))))

Even after that I have trouble following your logic. For example, when something is a cons, then you should process both the car and the cdr, but you don't. I didn't go through the the debugging process, but you should.


Instead, I'd like to show you an alternative. I would suggest splitting the problem in 2 parts:

flattening the list

Since we start with a nested list but end up with a flat list, it's easier to flatten the list first. Here is a classical flatten function:

(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)))

processing the flat list

Now, with a flat list, the rest becomes obvious, using the member function (and calling my function find-from to distinguish it from yours at the REPL):

(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))))

testing

? (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)
于 2014-11-02T21:13:35.533 回答