2012-02-13 2 views
1

목표는 모든 내부 괄호를 제거하는 것입니다.내부 괄호를 제거하고 빈 목록으로 실행하고 단점을 사용하여 제거하지 않음

(평평 '(A (BC) D))이된다'(ABCD)는

이 그것은

procedure application: expected procedure, given: c; arguments were:() 

을 불평

; if slist is null, return empty 
; otherwise, if it is a pair, recursively solve car and cdr and concat them 
; if it is a symbol, return the symbol 

(define flatten 
    (lambda (slist) 
    (cond 
     [ (null? slist) '()] 
     [ (pair? slist) 
     (cons ((flatten (car slist)) (flatten (cdr slist))))] 
     [ (symbol? slist) slist]))) 

라켓 내 코드입니다 즉, 빈 목록에 carcdr에 액세스하려고합니다.

I did the trace: 
> (flatten '(a (b c) d)) 
pair?-car-cdr 
a 
((b c) d) 
symbol? 
a 
pair?-car-cdr 
(b c) 
(d) 
pair?-car-cdr 
b 
(c) 
symbol? 
b 
pair?-car-cdr 
c 
() 
symbol? 
c 
(stops here) 

추적 코드는 간단합니다. 이해가 안 무엇

(define flatten 
    (lambda (slist) 
    (cond 
     [ (null? slist) '()] 
     [ (pair? slist) 
     (display 'pair?-car-cdr) 
     (newline) 
     (display (car slist)) 
     (newline) 
     (display (cdr slist)) 
     (newline) 
     (cons ((flatten (car slist)) (flatten (cdr slist))))] 
     [ (symbol? slist) 
     (display 'symbol?) 
     (newline) 
     (display slist) 
     (newline) 
     slist]))) 

는 빈리스트를 잡을하지 않았다 첫 번째 조건 (null? slist) 와서 어떻게? 두 번의 재귀 호출이 있습니다. 빈 목록을 찾은 경우 목록 인 다음 재귀로 이동합니다 {d}.

내 재귀 논리의 문제점은 무엇입니까?


업데이트 버전

로스 라슨이 제안한 것처럼
(define flatten 
    (lambda (slist) 
    (cond 
     [ (null? slist) '()] 
     [ (pair? slist) 
     (cons (flatten (car slist)) (flatten (cdr slist)))] 
     [ (symbol? slist) slist]))) 

(display (equal? (flatten '(a (b a) b a c (a b) c (e f (b a)))) '(a b a b a c a b c e f b a))) 
(newline) 
(display (equal? (flatten '(a b c)) '(a b c))) 
(newline) 
(display (equal? (flatten '(a (b c))) '(a b c))) 
(newline) 
(display (equal? (flatten '((a)(b)(c) d)) '(a b c d))) 
(newline) 
(display (equal? (flatten '(a (b) ((c)) (((d))) ((((e (f g))))))) '(a b c d e f g))) 
(newline) 
(display (equal? (flatten '()) '())) 
(newline) 
(display (equal? (flatten '(a b()())) '(a b))) 
(newline) 

, 프로그램이 작동하는지 확인합니다 추가합니다. 하나는 여분의 시간이하지만 학습을 위해, 내 테스트의 결과는 내가 (cons (flatten slist) empty)

를 호출하는 래퍼 함수를 ​​작성하는 생각

에만 전달되는 기본 케이스 (2 및 빈리스트)를 보여

((평평 (자동차 SLIST)) ...)

이 의미, 무엇이든 (평평하게 ...) 수익률을 적용

+0

그냥 더블 확인

http://docs.racket-lang.org/reference/pairs.html

(이것은 다른 답변을 재귀 값의 적용 문제를 해결 한 것 같다 나는 다른 문제를 해결하지 않음) : DrRacket 제대로 코드의 영역을 강조 않았다'((flatten (car slist)) (flatten (cdr slist)))'오류가 발생 했습니까? 그렇게해야하며, GUI가 올바른 일을하고 있는지 확인하고 싶습니다. – dyoo

+0

@dyoo 네, 맞습니다. 감사. – CppLearner

답변

5

문제는이 표현입니다. 그러나이 이 목록을 반환하기 때문에 응용 프로그램이 실패합니다.

변경을 (평평 (자동차 SLIST))

+0

예. 원래 줄을'(consten (flatten (car slist)) (flatten (cdr slist)) '로 바꾸면 문제가 해결됩니다.)하지만 내 논리는 완전히 잘못 되었습니까? 반환은 수정되지 않은 목록이므로. 새로운 질문을해야합니까? – CppLearner

+0

테스트 케이스가 있습니까? 어떤 테스트 케이스가 작동하고 어떤 테스트 케이스가 작동하지 않는가? – soegaard

+0

오른쪽. 나는 그랬다. 기본 케이스 만'단점 '으로 통과 할 것입니다. 로스 라슨 (Ross Larson)은 '추가'를 사용하여 제안함으로써 다른 문제를 해결했습니다. 'flatten'을 호출하는 래퍼 함수가 있어야만합니다. – CppLearner

1

죄수 (당신이 관찰 한 것처럼) 구조를 다시 것입니다. 대신에 추가로 살펴보십시오.

+0

예. 추가 기능이 작동합니다. 하지만 내가 단점을 사용한다면 그건 실현 가능할까요? 필자는'flatten'을 호출하는 wrapper 함수를 만들려고했다. – CppLearner

+0

단점은 벗겨지지 않을 것입니다. 그래서 만약 당신이 '((1 2) 3)을 가지고 있다면 (cons (flatten'(1 2)) (flatten '(3))) 그것들은 모두 flat list이므로, (1 2) '(3))'(1 2)는 목록의 차 위치에 놓이게된다 '(3). (append는 목록의 각 요소를 꺼내 두 번째 목록에 개별적으로 추가합니다. –

관련 문제