2014-10-17 6 views
0

나는 DrRacket을 배우고 있으며 목록을 뒤집는 프로그램을 작성해야합니다. 나는 아래 숫자를 가지고 있으며 숫자를 뒤집지 만 목록이나 뭔가 안에 어떻게 든 중첩시킨다. 의목록 오류 반전

(define (reverse-list lon) 
    (if (empty? lon) 
     empty 
     (cons (reverse-list (rest lon)) 
      (cons (first lon) 
        empty)))) 

출력 (역리스트 (목록 1 2 3 4)) : 출력이 하나 개의 목록으로 나오고되지 않는 이유

(list (list (list (list empty 4) 3) 2) 1) 

누구나 알아?

도움 주셔서 감사합니다.

답변

0

그럼 결국 작업을 끝내자. 첫 번째 단점을 추가하여 중첩 목록을 중지했다.

(define (reverse-list lon) 
    (if (empty? lon) empty (append (reverse-list (rest lon)) (cons (first lon) empty)))) 

문제가 해결되었습니다. 도움을 주셔서 감사합니다.

1

cons에는 2 개의 셀이 있습니다. carcdr. 셀은 (a . b)으로 표시 될 수 있습니다. 여기서 ab은 어떤 것이 될 수 있습니다.

쌍으로 표시되는 대체 표현이 있습니다. b이 다른 쌍이거나 빈 목록 인 경우 . b)b으로 바꿀 수 있습니다.이 경우 (이 붙지 않습니다. 따라서 :

(a .())    ; ==> (a) 
(a . (b . c))  ; ==> (a b . c) 
(a . (b . (c .()))) ; ==> (a b c) 

이제 코드를 작성하십시오. (1 2 3 4) (또는 정확하게는 (1 . (2 . (3 . (4 .())))))을 사용해보십시오. substitution rules을 사용하여 귀하의 절차가 정확히 무엇인지 계산합니다 :

(reverse-list '(1 . (2 . (3 . (4 .())))))     ; ==> 
(if (empty? '(1 . (2 . (3 . (4 .()))))) 
    empty 
    (cons (reverse-list (rest '(1 . (2 . (3 . (4 .())))))) 
      (cons (first '(1 . (2 . (3 . (4 .()))))) 
       empty)))          ; ==> 
(if #f 
    empty 
    (cons (reverse-list (rest '(1 . (2 . (3 . (4 .())))))) 
      (cons (first '(1 . (2 . (3 . (4 .()))))) 
       empty)))          ; ==> 

(cons (reverse-list '(2 . (3 . (4 .())))) 
     (cons 1 empty))          ; ==> 

(cons (cons (reverse-list '(3 . (4 .()))) 
      (cons 2 empty)) 
     (cons 1 empty))          ; ==> 

(cons (cons (cons (reverse-list '(4 .())) 
        (cons 3 empty)) 
      (cons 2 empty)) 
     (cons 1 empty))          ; ==> 

(cons (cons (cons (cons (reverse-list '()) 
         (cons 4 empty)) 
        (cons 3 empty)) 
      (cons 2 empty)) 
     (cons 1 empty))          ; ==> 

(cons (cons (cons (cons '() 
         (cons 4 empty)) 
        (cons 3 empty)) 
      (cons 2 empty)) 
     (cons 1 empty))          ; ==> 

((((() . (4 .())) . (3 .())) . (2 .())) . (1 .()))  ; ==> 
((((() . (4)) . (3)) . (2)) . (1))       ; ==> 
((((() 4) 3) 2) 1) 

Now. 사실 반전 된 목록은 점으로 구분 된 표기법으로 다음과 같이 보입니다.

(4 . (3 . (2 . (1 .())))) ; ==> (4 3 2 1) 

주위를 둘러 볼 방법이 없습니다. cons과 매우 친밀 해져야하며 다양한 구성 방법이 표시되는 방법을 알고 있어야합니다. 힌트는 거의 모든 목록이 처음부터 끝까지 만들어지고 처음부터 끝까지 반복된다는 것입니다.

+0

그래서 난 정말 당신이 무슨 말을하는지받지 못했습니다. 그것은 "빈"과 관련이있는 것처럼 보입니다. 그러나 drracket이 그것 없이는 나에게 단념시키지 않을 것이기 때문에 그것을 넣습니다. – Acoustic77

+3

"빈"이 문제가 아니며 "단점"을 사용합니다. 단점은 항목과 목록의 두 가지를 취합니다. '(cons 1 '(2 3 4))'는 (1 2 3 4)'를줍니다. 당신은 단점의 사용법으로 전체 목록 *을 첫 번째 위치에 넣습니다. '(cons (1 2) '(3 4))'=>''((1 2) 3 4)'그래서 이상한 중첩을 얻는다. Sylwester가 말한 것은''왜''가 무엇을하는지, 어떻게 사용하는지, 그리고 빈리스트에 항목을 하나씩 추가하여리스트가 만들어져 코드가 잘못된 것을 이해하는 것입니다. – Jack

1

자신 만의 문제를 해결하게되어 반갑습니다. 그러나 나는 목록을 뒤집는 것이 실제로 당신의 방식으로 하나를 반복하는 것이므로 약간을 골라야한다고 생각한다.

(define (reverse-list lon) 
    ;; iterative helper procedure 
    (define (aux lon acc) 
    (if (empty? lon) 
     acc 
     (aux (rest lon) 
      (cons (first lon) acc)))) 
    ;; use helper 
    (aux lon empty)) 

(reverse-list '(1 2 3 4)) ; ==> (4 3 2 1) 

우리가 처음부터 끝까지 반복 볼 수 있듯이. 우리가 그렇게 할 때 우리는 지금까지 누적 된 목록에 현재 요소를 고집하며 그 동작은 처음부터 끝까지 있습니다. E.i. 마지막으로 추가 된 요소가 결과의 첫 번째 요소가됩니다. 이것에 대한 좋은 점은 처리 된 각 셀에 대해 하나의 새 셀을 사용한다는 것이며 최종 결과의 일부가된다는 것입니다. append을 사용할 때마다 n 요소 목록에 (apply + (range n)) 불필요한 셀이 할당되도록 첫 번째 인수를 복사합니다.

더 노련한 음모가 로컬 프로 시저를 모두 할 명명 된 let을 사용하고 한 번에 전화 :

(define (reverse-list lon) 
    (let aux ((lon lon) (acc empty)) 
    (if (empty? lon) 
     acc 
     (aux (rest lon) 
      (cons (first lon) acc)))))