2012-02-18 7 views
0

저는 Lisp을 처음 사용하고 기존 목록에 목록을 추가 할 때 문제가 있습니다.재귀 후 반환 목록이 중복됩니다.

(기능 사양) 다음 함수는 2 개의 인수를 사용합니다. 원자와 목록. 목록은 각 하위 목록이 (index counter) 인 것처럼 2 차원 형식을 취합니다 (색인 및 카운터는 모두 원자입니다). targetindex 중 하나와 같으면 counter 씩 증가합니다. 더 하위 목록이 target가없는 경우, target 아직 존재하지 않는 경우 문제가 counter = 1

(defun contained (target list) 
    (cond ((null list) (list target 1)) 
    ((= (car (car list)) target) 
    (setf (cadr (car list)) 
      (+ (cadr (car list)) 1))) 
    (t (push (contained target (cdr list)) list)))) 

으로 새 하위 목록을 추가 할 수 있습니다. 아래에 표시된 것처럼 목록과 괄호는 중복됩니다.

> la 
((1 4) (2 1)) 
> (contained 3 la) 
(((3 1) (2 1)) (1 4) (2 1)) 

는 내가 원하는 뭔가 같은 :

((3 1) (1 4) (2 1)) 
문제를 단순화 할 수있었습니다하지 죄송

하지만, 감사합니다.

(defun contained (target list) 
    (let ((elm (assoc target list))) 
     (if elm 
      (progn (incf (cadr elm)) list) 
      (cons (list target 1) list)))) 

여기에 원래

에 더 가까이 할 수있는 방법이있다 : 당신을 위해 당신의 숙제를 위험에서

답변

2
(defun contained (target list) 
    (cond 
    ((null list) (list target 1)) ; you are returning a new element of target 

    ((= (car (car list)) target) 
    (setf (cadr (car list)) 
      (+ (cadr (car list)) 1))) ; you are returning... what? 

    ;; yet you are pushing on every recursive call! 
    (t (push (contained target (cdr list)) list)))) 

, 여기 (MIRON Brezuleanu의 도움으로) 그것을 할 수있는 하나의 방법
(defun contained (target list) 
    (cond 
    ((null list) (list (list target 1))) 
    ((= (car (car list)) target) 
    (setf (cadr (car list)) 
      (+ (cadr (car list)) 1)) 
    list) 
    (t (setf (cdr list) (contained target (cdr list))) 
     list))) 
+0

감사합니다. 지금까지'elm'의 정의를 찾지 못했기 때문에 특히 원본에 더 가까운 것을 고맙게 생각합니다. – IsaacS

+0

이 특수한 경우에 "elm"은 "element"(elt와 비슷합니다)의 약자 인 것으로 보입니다. – Vatine

+0

'elm'은 let 형식으로 묶인 변수입니다. 그러나 포함 된 특정 버전은 나에게 이상하게 보입니다. 'if'의 한 분기에서 다른 한리스트에 정수를 반환합니다. 어떻게 그런 함수를 사용할 수 있을지 모르겠다. :-) 저자가 의도 한 것일 수도있다. (defun 포함 (대상 목록) ) ((progn iff cadr elm) 목록) (cons (cons target 1) list))))'? ('assoc'의 사용은 목록의 요소가 목록이 아니라 conses라고 가정합니다). –

관련 문제