2012-04-30 4 views
0

내부 목록을 포함하는 목록에서 요소를 제거해야합니다. 사전 정의 된 요소는 모든 내부 목록에서도 제거해야합니다. 나는 다음과 같은 코드로 작업을 시작했습니다LISP - 중첩 목록이있는 목록에서 요소 제거

:

(SETQ L2 '(a b (a 2 b) c 1 2 (D b (a s 4 2) c 1 2 a) a)) ; defined my list 

; Created a function for element removing 
(defun elimina (x l &optional l0) 
(cond ((null l)(reverse l0)) 
((eq x (car l))(elimina x (cdr l) l0)) 
(T (elimina x (cdr l) (cons (car l) l0)))) 
) 

(ELIMINA 'a L2) 

는 그러나 불행하게도 그것은 중첩 된 목록 외부 요소 만 제거합니다.

내부 목록에서 요소를 제거하는 추가 기능을 만들려고했습니다.

(defun elimina-all (x l) 
(cond ((LISTP (CAR L))(reverse l)(elimina x (car l))) 
(T (elimina-all x (CDR L))) 
) 
) 

여전히 성공적이지 못합니다.

해결해 주시겠습니까?

미리 감사드립니다. 어쩌면이 같은

+1

이 숙제가 있습니까? 예인 경우 숙제 태그를 추가하십시오. –

+4

코드를 올바르게 들여 쓰기해야합니다. 지금은 읽기가 어렵습니다. –

답변

0

: 모든

(defun elimina (x l &optional l0) 
    (cond ((null l) (reverse l0)) 
     ((eq x (car l)) (elimina x (cdr l) l0)) 
     (T (elimina x (cdr l) (cons (if (not (atom (car l))) 
             (elimina x (car l)) 
             (car l)) 
            l0))))) 
+0

이것은 좋은 해결책입니다. 감사합니다. 그러나 목록에서 요소 집합을 제거하는 데는 작동하지 않습니다. 예 : (ELIMINA (a2 b) L2) – e20

+0

그럴 경우'((원자 x) (eq x (car l)) (멤버 (car l) x))'와 함께 eq x (car l) –

+0

'(member (car l) x)'를 사용하면리스트의 첫 번째 멤버 만 전체 목록에서 제거됩니다. 그러나 실제로 요점은'(A (A 2 B))'목록 (L2)에서'(A 2 B)'를 제거하는 것입니다. – e20

2

첫째, 당신이이 책을 읽는 게 좋을 것, (아주 좋은 예제도 제공합니다!) 이상, this page, 그것을 설명하는 트리를 탐색하는 방법 가장 중요한 것은 더 복잡한 작업을보다 간단한 작업에서 활용하는 기능을 결합하는 방법입니다.

;; Note that this function is very similar to the built-in 
;; `remove-if' function. Normally, you won't write this yourself 
(defun remove-if-tree (tree predicate) 
    (cond 
    ((null tree) nil) 
    ((funcall predicate (car tree)) 
    (remove-if-tree (cdr tree) predicate)) 
    ((listp (car tree)) 
    (cons (remove-if-tree (car tree) predicate) 
      (remove-if-tree (cdr tree) predicate))) 
    (t (cons (car tree) 
      (remove-if-tree (cdr tree) predicate))))) 

;; Note that the case of the symbol names doesn't matter 
;; with the default settings of the reader table. I.e. `D' and `d' 
;; are the same symbol, both uppercase. 
;; Either use \ (backslash) or || (pipes 
;; around the symbol name to preserve the case. Eg. \d is the 
;; lowercase `d'. Similarly, |d| is a lowercase `d'. 
(format t "result: ~s~&" 
     (remove-if-tree 
     '(a b (a 2 b) c 1 2 (D b (a s 4 2) c 1 2 a) a) 
     #'(lambda (x) (or (equal 1 x) (equal x 'a))))) 

다음은 문제를 해결하는 방법 중 하나입니다. 의견을 읽으십시오.

0

나는 당신과 같은 대답을 찾고 있었고, 불행하게도 나는 위의 답을 완전히 이해할 수 없었고 그래서 나는 그것에 대해 연구했다. 그리고 마침내 나는 네가 원하는 것을 정확하게 수행하는 아주 간단한 함수를 얻었다.

(defun remove (a l) 
(cond 
    ((null l)()) 
     ((listp (car l))(cons (remove a (car l))(remove a (cdr l)))) 
     ((eq (car l) a) (remove a (cdr l))) 
     (t (cons (car l) (remove a (cdr l)))) 
     ) 
    ) 

이 함수는 'list is null'과 'first element is list'의 두 가지 간단한 경우로 시작됩니다. 다음으로 당신은 주어진 요소없이 목록의 car과 목록의 cdr을 "마술처럼"얻을 것입니다. 전체 목록에 대한 답변이되도록 수정하려면 cons을 사용하면됩니다.